fluent-plugin-opensearch 1.1.6 → 1.1.7
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 +4 -4
- data/.github/dependabot.yml +17 -0
- data/.github/workflows/add-to-project.yml +2 -2
- data/.github/workflows/coverage.yaml +3 -3
- data/.github/workflows/linux.yml +2 -2
- data/.github/workflows/macos.yml +2 -2
- data/.github/workflows/windows.yml +2 -2
- data/History.md +7 -0
- data/README.md +36 -3
- data/fluent-plugin-opensearch.gemspec +1 -1
- data/lib/fluent/plugin/in_opensearch.rb +1 -1
- data/lib/fluent/plugin/opensearch_index_template.rb +2 -2
- data/lib/fluent/plugin/out_opensearch.rb +18 -11
- data/test/plugin/test_opensearch_error_handler.rb +0 -1
- data/test/plugin/test_out_opensearch.rb +118 -1
- metadata +2 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 59ef255b7e5cb5ceae9b97b0678cdc7151f0514263934f21e1028a45220180d6
|
|
4
|
+
data.tar.gz: 7603936854d8a36c74b6fa6ee4187b089cd781c997da8b97eed21fafbd52833c
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 4caf0aa8ff2803a46536db82defff7b203f837dea3e2fc97b46487a04c9d85c5b4f71b9145985e9616e4db54f4bdef93a61ca85d941612474794276bdbf37531
|
|
7
|
+
data.tar.gz: b9fb24c499f3c84ece032e744a567ee9c34b7b8a2f47c39a706408e80fb7c8f19624499d447ed4191e75333c4050ef79237e51037dd0122ea95fc7aa6ad6f097
|
data/.github/dependabot.yml
CHANGED
|
@@ -4,3 +4,20 @@ updates:
|
|
|
4
4
|
directory: '/'
|
|
5
5
|
schedule:
|
|
6
6
|
interval: 'monthly'
|
|
7
|
+
groups:
|
|
8
|
+
# PR: "Security update [package] from [old] to [new]"
|
|
9
|
+
# This PR should be merged in hurry
|
|
10
|
+
security-updates:
|
|
11
|
+
applies-to: security-updates
|
|
12
|
+
patterns:
|
|
13
|
+
- '*'
|
|
14
|
+
|
|
15
|
+
# PR: "Bump [package] from [old] to [new]"
|
|
16
|
+
# No need to be merged this PR in hurry. It is enough to merge
|
|
17
|
+
# once in a month.
|
|
18
|
+
monthly-updates:
|
|
19
|
+
applies-to: version-updates
|
|
20
|
+
patterns:
|
|
21
|
+
- '*'
|
|
22
|
+
# Allow to create PR both of security and normal updates.
|
|
23
|
+
open-pull-requests-limit: 1
|
|
@@ -12,12 +12,12 @@ jobs:
|
|
|
12
12
|
steps:
|
|
13
13
|
- name: Generate token
|
|
14
14
|
id: generate_token
|
|
15
|
-
uses: actions/create-github-app-token@
|
|
15
|
+
uses: actions/create-github-app-token@bcd2ba49218906704ab6c1aa796996da409d3eb1 # v3.2.0
|
|
16
16
|
with:
|
|
17
17
|
app-id: ${{ secrets.PROJECT_APP_ID }}
|
|
18
18
|
private-key: ${{ secrets.PROJECT_APP_PRIVATE_KEY }}
|
|
19
19
|
owner: fluent
|
|
20
|
-
- uses: actions/add-to-project@
|
|
20
|
+
- uses: actions/add-to-project@5afcf98fcd03f1c2f92c3c83f58ae24323cc57fd # v2.0.0
|
|
21
21
|
with:
|
|
22
22
|
project-url: https://github.com/orgs/fluent/projects/4
|
|
23
23
|
github-token: ${{ steps.generate_token.outputs.token }}
|
|
@@ -6,9 +6,9 @@ jobs:
|
|
|
6
6
|
coverage:
|
|
7
7
|
runs-on: ubuntu-latest
|
|
8
8
|
steps:
|
|
9
|
-
- uses: actions/checkout@
|
|
9
|
+
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
|
10
10
|
- name: Set up Ruby 3.0
|
|
11
|
-
uses: ruby/setup-ruby@
|
|
11
|
+
uses: ruby/setup-ruby@95ef2b042f9d7a56d8268cba8559e2842e2ad01b # v1.321.0
|
|
12
12
|
with:
|
|
13
13
|
ruby-version: '3.1'
|
|
14
14
|
- name: Build and test with Rake
|
|
@@ -16,6 +16,6 @@ jobs:
|
|
|
16
16
|
bundle install
|
|
17
17
|
bundle exec rake
|
|
18
18
|
- name: Coveralls GitHub Action
|
|
19
|
-
uses: coverallsapp/github-action@
|
|
19
|
+
uses: coverallsapp/github-action@8d6379e14d29928660c4ba802d8e85393440b329 # v2.3.8
|
|
20
20
|
with:
|
|
21
21
|
github-token: ${{ secrets.GITHUB_TOKEN }}
|
data/.github/workflows/linux.yml
CHANGED
|
@@ -25,8 +25,8 @@ jobs:
|
|
|
25
25
|
- ubuntu-latest
|
|
26
26
|
name: Ruby ${{ matrix.ruby }} unit testing on ${{ matrix.os }}
|
|
27
27
|
steps:
|
|
28
|
-
- uses: actions/checkout@
|
|
29
|
-
- uses: ruby/setup-ruby@
|
|
28
|
+
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
|
29
|
+
- uses: ruby/setup-ruby@95ef2b042f9d7a56d8268cba8559e2842e2ad01b # v1.321.0
|
|
30
30
|
with:
|
|
31
31
|
ruby-version: ${{ matrix.ruby }}
|
|
32
32
|
- name: unit testing
|
data/.github/workflows/macos.yml
CHANGED
|
@@ -25,8 +25,8 @@ jobs:
|
|
|
25
25
|
- macOS-latest
|
|
26
26
|
name: Ruby ${{ matrix.ruby }} unit testing on ${{ matrix.os }}
|
|
27
27
|
steps:
|
|
28
|
-
- uses: actions/checkout@
|
|
29
|
-
- uses: ruby/setup-ruby@
|
|
28
|
+
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
|
29
|
+
- uses: ruby/setup-ruby@95ef2b042f9d7a56d8268cba8559e2842e2ad01b # v1.321.0
|
|
30
30
|
with:
|
|
31
31
|
ruby-version: ${{ matrix.ruby }}
|
|
32
32
|
- name: unit testing
|
|
@@ -25,8 +25,8 @@ jobs:
|
|
|
25
25
|
- windows-latest
|
|
26
26
|
name: Ruby ${{ matrix.ruby }} unit testing on ${{ matrix.os }}
|
|
27
27
|
steps:
|
|
28
|
-
- uses: actions/checkout@
|
|
29
|
-
- uses: ruby/setup-ruby@
|
|
28
|
+
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
|
29
|
+
- uses: ruby/setup-ruby@95ef2b042f9d7a56d8268cba8559e2842e2ad01b # v1.321.0
|
|
30
30
|
with:
|
|
31
31
|
ruby-version: ${{ matrix.ruby }}
|
|
32
32
|
- name: unit testing
|
data/History.md
CHANGED
|
@@ -2,6 +2,13 @@
|
|
|
2
2
|
|
|
3
3
|
### [Unreleased]
|
|
4
4
|
|
|
5
|
+
### 1.1.7
|
|
6
|
+
- test: remove duplicate keys from bulk response fixtures (#190)
|
|
7
|
+
- out\_opensearch: keep AWS credential providers refreshable to fix expired SigV4 tokens with assume\_role\_arn (#188)
|
|
8
|
+
- docs: document OpenSearch Serverless startup version-check workaround (#186)
|
|
9
|
+
- Allow duplicate keys in JSON parser (#185)
|
|
10
|
+
- Replace yajl-ruby with the json gem for JSON handling (#183)
|
|
11
|
+
|
|
5
12
|
### 1.1.6
|
|
6
13
|
- out\_opensearch\_data\_stream: filter failed items in data stream bulk error log (#175)
|
|
7
14
|
- out\_opensearch: fix default value of `refresh_credentials_interval` (#159)
|
data/README.md
CHANGED
|
@@ -902,7 +902,7 @@ compression_level best_compression
|
|
|
902
902
|
|
|
903
903
|
### prefer_oj_serializer
|
|
904
904
|
|
|
905
|
-
With default behavior, OpenSearch client uses `
|
|
905
|
+
With default behavior, OpenSearch client uses `JSON` as JSON encoder/decoder.
|
|
906
906
|
`Oj` is the alternative high performance JSON encoder/decoder.
|
|
907
907
|
When this parameter sets as `true`, OpenSearch client uses `Oj` as JSON encoder/decoder.
|
|
908
908
|
|
|
@@ -1568,7 +1568,7 @@ In this case, the endpoint configuration looks like:
|
|
|
1568
1568
|
|
|
1569
1569
|
### Expiring AWS credentials
|
|
1570
1570
|
|
|
1571
|
-
If you want to
|
|
1571
|
+
Credentials obtained from STS, IMDS or ECS are refreshed by the AWS SDK before they expire, so you usually do not need to change this parameter. If you want to recreate the credential provider forcibly in a certain interval, you should specify `refresh_credentials_interval` parameter under `endpoint` section:
|
|
1572
1572
|
|
|
1573
1573
|
```aconf
|
|
1574
1574
|
<endpoint>
|
|
@@ -1581,7 +1581,7 @@ If you want to expire AWS credentials in certain interval, you should specify `r
|
|
|
1581
1581
|
|
|
1582
1582
|
### Use OpenSearch Serverless
|
|
1583
1583
|
|
|
1584
|
-
If you want to use Serverless version of OpenSearch service, you have to specify `aoss` in `aws_service_name` under `endpoint` section:
|
|
1584
|
+
If you want to use the Serverless version of OpenSearch service, you have to specify `aoss` in `aws_service_name` under the `endpoint` section:
|
|
1585
1585
|
|
|
1586
1586
|
```aconf
|
|
1587
1587
|
<endpoint>
|
|
@@ -1592,6 +1592,39 @@ If you want to use Serverless version of OpenSearch service, you have to specify
|
|
|
1592
1592
|
</endpoint>
|
|
1593
1593
|
```
|
|
1594
1594
|
|
|
1595
|
+
**NOTE:** OpenSearch Serverless only supports a subset of the OpenSearch APIs and does **not** serve the root/info endpoint (`GET /`) that this plugin uses to detect the OpenSearch major version at startup. If you leave the default `verify_os_version_at_startup true`, the plugin fails the version probe with `404`, keeps retrying, and never starts sending data:
|
|
1596
|
+
|
|
1597
|
+
```
|
|
1598
|
+
Could not communicate to OpenSearch, resetting connection and trying again. [404]
|
|
1599
|
+
```
|
|
1600
|
+
|
|
1601
|
+
To avoid this, disable the startup version check and pin the version (Serverless is OpenSearch 2.x compatible):
|
|
1602
|
+
|
|
1603
|
+
```aconf
|
|
1604
|
+
<match es.**>
|
|
1605
|
+
@type opensearch
|
|
1606
|
+
logstash_format true
|
|
1607
|
+
include_tag_key true
|
|
1608
|
+
flush_interval 1s
|
|
1609
|
+
|
|
1610
|
+
# Serverless does not serve GET /, so skip the version probe.
|
|
1611
|
+
verify_os_version_at_startup false
|
|
1612
|
+
default_opensearch_version 2
|
|
1613
|
+
|
|
1614
|
+
<endpoint>
|
|
1615
|
+
url https://CLUSTER_ENDPOINT_URL
|
|
1616
|
+
region us-east-2
|
|
1617
|
+
aws_service_name aoss
|
|
1618
|
+
</endpoint>
|
|
1619
|
+
</match>
|
|
1620
|
+
```
|
|
1621
|
+
|
|
1622
|
+
**Other Serverless limitations to keep in mind:**
|
|
1623
|
+
|
|
1624
|
+
- Your IAM identity needs a **data access policy** on the collection (at least `aoss:CreateIndex` and `aoss:WriteDocument`). An IAM permission policy alone is not sufficient.
|
|
1625
|
+
- For `TIMESERIES` collections, custom document IDs are not supported. Do not set `id_key`, and keep the default `write_operation index`, since `create` / `update` / `upsert` require an `_id`.
|
|
1626
|
+
- Index templates, rollover/ILM, and data streams rely on APIs that Serverless does not expose, so template-related options and `@type opensearch_data_stream` are not usable against a Serverless collection.
|
|
1627
|
+
|
|
1595
1628
|
## Troubleshooting
|
|
1596
1629
|
|
|
1597
1630
|
See [Troubleshooting document](README.Troubleshooting.md)
|
|
@@ -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.1.
|
|
6
|
+
s.version = '1.1.7'
|
|
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}
|
|
@@ -374,7 +374,7 @@ module Fluent::Plugin
|
|
|
374
374
|
def run_slice(slice_id=nil)
|
|
375
375
|
slice_query = @base_query
|
|
376
376
|
slice_query = slice_query.merge('slice' => { 'id' => slice_id, 'max' => @num_slices}) unless slice_id.nil?
|
|
377
|
-
result = client.search(@options.merge(:body =>
|
|
377
|
+
result = client.search(@options.merge(:body => JSON.generate(slice_query) ))
|
|
378
378
|
es = Fluent::MultiEventStream.new
|
|
379
379
|
|
|
380
380
|
result["hits"]["hits"].each {|hit| process_events(hit, es)}
|
|
@@ -33,7 +33,7 @@ module Fluent::OpenSearchIndexTemplate
|
|
|
33
33
|
raise "If you specify a template_name you must specify a valid template file (checked '#{template_file}')!"
|
|
34
34
|
end
|
|
35
35
|
file_contents = IO.read(template_file).gsub(/\n/,'')
|
|
36
|
-
JSON.parse(file_contents)
|
|
36
|
+
JSON.parse(file_contents, allow_duplicate_key: true)
|
|
37
37
|
end
|
|
38
38
|
|
|
39
39
|
def get_custom_template(template_file, customize_template)
|
|
@@ -44,7 +44,7 @@ module Fluent::OpenSearchIndexTemplate
|
|
|
44
44
|
customize_template.each do |key, value|
|
|
45
45
|
file_contents = file_contents.gsub(key,value.downcase)
|
|
46
46
|
end
|
|
47
|
-
JSON.parse(file_contents)
|
|
47
|
+
JSON.parse(file_contents, allow_duplicate_key: true)
|
|
48
48
|
end
|
|
49
49
|
|
|
50
50
|
def template_exists?(name, host = nil)
|
|
@@ -225,13 +225,13 @@ module Fluent::Plugin
|
|
|
225
225
|
if conf[:assume_role_arn].nil?
|
|
226
226
|
aws_container_credentials_relative_uri = conf[:ecs_container_credentials_relative_uri] || ENV["AWS_CONTAINER_CREDENTIALS_RELATIVE_URI"]
|
|
227
227
|
if aws_container_credentials_relative_uri.nil?
|
|
228
|
-
credentials = Aws::SharedCredentials.new
|
|
229
|
-
credentials ||= Aws::InstanceProfileCredentials.new
|
|
230
|
-
credentials ||= Aws::ECSCredentials.new
|
|
228
|
+
credentials = usable_credentials_provider { Aws::SharedCredentials.new }
|
|
229
|
+
credentials ||= usable_credentials_provider { Aws::InstanceProfileCredentials.new }
|
|
230
|
+
credentials ||= usable_credentials_provider { Aws::ECSCredentials.new }
|
|
231
231
|
else
|
|
232
232
|
credentials = Aws::ECSCredentials.new({
|
|
233
233
|
credential_path: aws_container_credentials_relative_uri
|
|
234
|
-
})
|
|
234
|
+
})
|
|
235
235
|
end
|
|
236
236
|
else
|
|
237
237
|
if conf[:assume_role_web_identity_token_file].nil?
|
|
@@ -239,21 +239,28 @@ module Fluent::Plugin
|
|
|
239
239
|
role_arn: conf[:assume_role_arn],
|
|
240
240
|
role_session_name: conf[:assume_role_session_name],
|
|
241
241
|
region: sts_creds_region(conf)
|
|
242
|
-
})
|
|
242
|
+
})
|
|
243
243
|
else
|
|
244
244
|
credentials = Aws::AssumeRoleWebIdentityCredentials.new({
|
|
245
245
|
role_arn: conf[:assume_role_arn],
|
|
246
246
|
web_identity_token_file: conf[:assume_role_web_identity_token_file],
|
|
247
247
|
region: sts_creds_region(conf)
|
|
248
|
-
})
|
|
248
|
+
})
|
|
249
249
|
end
|
|
250
250
|
end
|
|
251
251
|
end
|
|
252
|
-
raise "No valid AWS credentials found." unless credentials
|
|
252
|
+
raise "No valid AWS credentials found." unless credentials&.credentials&.set?
|
|
253
253
|
|
|
254
254
|
credentials
|
|
255
255
|
end
|
|
256
256
|
|
|
257
|
+
def usable_credentials_provider
|
|
258
|
+
provider = yield
|
|
259
|
+
provider if provider.credentials&.set?
|
|
260
|
+
rescue
|
|
261
|
+
nil
|
|
262
|
+
end
|
|
263
|
+
|
|
257
264
|
def sts_creds_region(conf)
|
|
258
265
|
conf[:sts_credentials_region] || conf[:region]
|
|
259
266
|
end
|
|
@@ -339,7 +346,7 @@ module Fluent::Plugin
|
|
|
339
346
|
}
|
|
340
347
|
end
|
|
341
348
|
end
|
|
342
|
-
#
|
|
349
|
+
# Credential providers refresh themselves near expiration. This timer recreates them forcibly.
|
|
343
350
|
@credential_mutex = Mutex.new
|
|
344
351
|
if @endpoint
|
|
345
352
|
@_aws_credentials = aws_credentials(@endpoint)
|
|
@@ -369,7 +376,7 @@ module Fluent::Plugin
|
|
|
369
376
|
OpenSearch::API.settings[:serializer] = Fluent::Plugin::Serializer::Oj
|
|
370
377
|
end
|
|
371
378
|
rescue LoadError
|
|
372
|
-
@dump_proc =
|
|
379
|
+
@dump_proc = JSON.method(:generate)
|
|
373
380
|
end
|
|
374
381
|
|
|
375
382
|
raise Fluent::ConfigError, "`password` must be present if `user` is present" if @user && @password.nil?
|
|
@@ -630,7 +637,7 @@ module Fluent::Plugin
|
|
|
630
637
|
:aws_sigv4,
|
|
631
638
|
service: @endpoint.aws_service_name.to_s,
|
|
632
639
|
region: @endpoint.region,
|
|
633
|
-
|
|
640
|
+
credentials_provider: @_aws_credentials,
|
|
634
641
|
)
|
|
635
642
|
|
|
636
643
|
f.adapter @http_backend, @backend_options
|
|
@@ -940,7 +947,7 @@ module Fluent::Plugin
|
|
|
940
947
|
{"_index" => {"order" => "desc"}}
|
|
941
948
|
]
|
|
942
949
|
}
|
|
943
|
-
result = client.search(options.merge(:body =>
|
|
950
|
+
result = client.search(options.merge(:body => JSON.generate(query)))
|
|
944
951
|
# There should be just one hit per _id, but in case there still is multiple, just the oldest index is stored to map
|
|
945
952
|
result['hits']['hits'].each do |hit|
|
|
946
953
|
indices[hit["_id"]] = hit["_index"]
|
|
@@ -85,6 +85,27 @@ class OpenSearchOutputTest < Test::Unit::TestCase
|
|
|
85
85
|
}
|
|
86
86
|
end
|
|
87
87
|
|
|
88
|
+
def chained_credentials_conf
|
|
89
|
+
{
|
|
90
|
+
access_key_id: '',
|
|
91
|
+
secret_access_key: '',
|
|
92
|
+
assume_role_arn: nil,
|
|
93
|
+
ecs_container_credentials_relative_uri: nil,
|
|
94
|
+
}
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
def with_stubbed_aws_responses
|
|
98
|
+
saved = Aws.config.key?(:stub_responses) ? Aws.config[:stub_responses] : :__unset__
|
|
99
|
+
Aws.config[:stub_responses] = true
|
|
100
|
+
yield
|
|
101
|
+
ensure
|
|
102
|
+
if saved == :__unset__
|
|
103
|
+
Aws.config.delete(:stub_responses)
|
|
104
|
+
else
|
|
105
|
+
Aws.config[:stub_responses] = saved
|
|
106
|
+
end
|
|
107
|
+
end
|
|
108
|
+
|
|
88
109
|
def stub_opensearch_info(url="http://localhost:9200/", version="1.2.2")
|
|
89
110
|
body ="{\"version\":{\"number\":\"#{version}\", \"distribution\":\"opensearch\"},\"tagline\":\"The OpenSearch Project: https://opensearch.org/\"}"
|
|
90
111
|
stub_request(:get, url).to_return({:status => 200, :body => body, :headers => { 'Content-Type' => 'json' } })
|
|
@@ -315,9 +336,106 @@ class OpenSearchOutputTest < Test::Unit::TestCase
|
|
|
315
336
|
assert_equal "fluentd", instance.endpoint.assume_role_session_name
|
|
316
337
|
assert_nil instance.endpoint.assume_role_web_identity_token_file
|
|
317
338
|
assert_nil instance.endpoint.sts_credentials_region
|
|
339
|
+
assert_equal 18000, instance.endpoint.refresh_credentials_interval
|
|
318
340
|
assert_equal :es, instance.endpoint.aws_service_name
|
|
319
341
|
end
|
|
320
342
|
|
|
343
|
+
test 'aws_credentials returns credential provider with access key' do
|
|
344
|
+
config = Fluent::Config::Element.new(
|
|
345
|
+
'ROOT', '', {
|
|
346
|
+
'@type' => 'opensearch',
|
|
347
|
+
}, [
|
|
348
|
+
Fluent::Config::Element.new('endpoint', '', {
|
|
349
|
+
'url' => "https://search-opensearch.aws.example.com/",
|
|
350
|
+
'region' => "local",
|
|
351
|
+
'access_key_id' => 'YOUR_AWESOME_KEY',
|
|
352
|
+
'secret_access_key' => 'YOUR_AWESOME_SECRET',
|
|
353
|
+
}, []),
|
|
354
|
+
Fluent::Config::Element.new('buffer', 'tag', {}, [])
|
|
355
|
+
|
|
356
|
+
])
|
|
357
|
+
instance = driver(config).instance
|
|
358
|
+
credentials = instance.aws_credentials(instance.endpoint)
|
|
359
|
+
|
|
360
|
+
assert_instance_of Aws::Credentials, credentials
|
|
361
|
+
assert_equal 'YOUR_AWESOME_KEY', credentials.credentials.access_key_id
|
|
362
|
+
end
|
|
363
|
+
|
|
364
|
+
test 'aws_credentials returns refreshable credential provider with assume_role_arn' do
|
|
365
|
+
with_stubbed_aws_responses do
|
|
366
|
+
config = Fluent::Config::Element.new(
|
|
367
|
+
'ROOT', '', {
|
|
368
|
+
'@type' => 'opensearch',
|
|
369
|
+
}, [
|
|
370
|
+
Fluent::Config::Element.new('endpoint', '', {
|
|
371
|
+
'url' => "https://search-opensearch.aws.example.com/",
|
|
372
|
+
'region' => "local",
|
|
373
|
+
'assume_role_arn' => 'arn:aws:iam::123456789012:role/some-role',
|
|
374
|
+
}, []),
|
|
375
|
+
Fluent::Config::Element.new('buffer', 'tag', {}, [])
|
|
376
|
+
|
|
377
|
+
])
|
|
378
|
+
instance = driver(config).instance
|
|
379
|
+
credentials = instance.aws_credentials(instance.endpoint)
|
|
380
|
+
|
|
381
|
+
assert_instance_of Aws::AssumeRoleCredentials, credentials
|
|
382
|
+
assert_kind_of Aws::RefreshingCredentials, credentials
|
|
383
|
+
assert_true credentials.credentials.set?
|
|
384
|
+
end
|
|
385
|
+
end
|
|
386
|
+
|
|
387
|
+
test 'aws_credentials falls back to the next provider when a provider has no credentials' do
|
|
388
|
+
unset_provider = flexmock('unset provider', credentials: Aws::Credentials.new(nil, nil))
|
|
389
|
+
ecs_provider = flexmock('ecs provider', credentials: Aws::Credentials.new('ECS_KEY', 'ECS_SECRET'))
|
|
390
|
+
flexmock(Aws::SharedCredentials).should_receive(:new).and_return(unset_provider)
|
|
391
|
+
flexmock(Aws::InstanceProfileCredentials).should_receive(:new).and_return(unset_provider)
|
|
392
|
+
flexmock(Aws::ECSCredentials).should_receive(:new).and_return(ecs_provider)
|
|
393
|
+
instance = driver.instance
|
|
394
|
+
|
|
395
|
+
assert_same ecs_provider, instance.aws_credentials(chained_credentials_conf)
|
|
396
|
+
end
|
|
397
|
+
|
|
398
|
+
test 'aws_credentials raises when no provider has usable credentials' do
|
|
399
|
+
unset_provider = flexmock('unset provider', credentials: Aws::Credentials.new(nil, nil))
|
|
400
|
+
flexmock(Aws::SharedCredentials).should_receive(:new).and_return(unset_provider)
|
|
401
|
+
flexmock(Aws::InstanceProfileCredentials).should_receive(:new).and_return(unset_provider)
|
|
402
|
+
flexmock(Aws::ECSCredentials).should_receive(:new)
|
|
403
|
+
.and_raise(ArgumentError.new("Cannot instantiate an ECS Credential Provider without a credential path or endpoint."))
|
|
404
|
+
instance = driver.instance
|
|
405
|
+
|
|
406
|
+
assert_raise(RuntimeError.new("No valid AWS credentials found.")) do
|
|
407
|
+
instance.aws_credentials(chained_credentials_conf)
|
|
408
|
+
end
|
|
409
|
+
end
|
|
410
|
+
|
|
411
|
+
test 'credentials provider is passed to aws_sigv4 middleware' do
|
|
412
|
+
with_stubbed_aws_responses do
|
|
413
|
+
config = Fluent::Config::Element.new(
|
|
414
|
+
'ROOT', '', {
|
|
415
|
+
'@type' => 'opensearch',
|
|
416
|
+
}, [
|
|
417
|
+
Fluent::Config::Element.new('endpoint', '', {
|
|
418
|
+
'url' => "https://search-opensearch.aws.example.com/",
|
|
419
|
+
'region' => "local",
|
|
420
|
+
'assume_role_arn' => 'arn:aws:iam::123456789012:role/some-role',
|
|
421
|
+
}, []),
|
|
422
|
+
Fluent::Config::Element.new('buffer', 'tag', {}, [])
|
|
423
|
+
|
|
424
|
+
])
|
|
425
|
+
instance = driver(config).instance
|
|
426
|
+
# Reaching into Faraday internals. If this breaks after a Faraday or
|
|
427
|
+
# faraday_middleware-aws-sigv4 update, check RackBuilder::Handler.
|
|
428
|
+
handler = instance.client.transport.transport.connections.first.connection.builder.handlers.find { |h|
|
|
429
|
+
h.klass == FaradayMiddleware::AwsSigV4
|
|
430
|
+
}
|
|
431
|
+
|
|
432
|
+
assert_not_nil handler
|
|
433
|
+
signer = handler.build(proc {}).instance_variable_get(:@signer)
|
|
434
|
+
assert_instance_of Aws::AssumeRoleCredentials, signer.credentials_provider
|
|
435
|
+
assert_same instance.instance_variable_get(:@_aws_credentials), signer.credentials_provider
|
|
436
|
+
end
|
|
437
|
+
end
|
|
438
|
+
|
|
321
439
|
data("OpenSearch Service" => [:es, 'es'],
|
|
322
440
|
"OpenSearch Serverless" => [:aoss, 'aoss'])
|
|
323
441
|
test 'configure endpoint section w/ aws_service_name' do |data|
|
|
@@ -3648,7 +3766,6 @@ class OpenSearchOutputTest < Test::Unit::TestCase
|
|
|
3648
3766
|
"_index" : "foo",
|
|
3649
3767
|
"_type" : "bar",
|
|
3650
3768
|
"_id" : "abc",
|
|
3651
|
-
"_id" : "abc",
|
|
3652
3769
|
"status" : 409
|
|
3653
3770
|
}
|
|
3654
3771
|
}
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: fluent-plugin-opensearch
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 1.1.
|
|
4
|
+
version: 1.1.7
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Hiroshi Hatake
|
|
@@ -270,7 +270,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
270
270
|
- !ruby/object:Gem::Version
|
|
271
271
|
version: '0'
|
|
272
272
|
requirements: []
|
|
273
|
-
rubygems_version: 4.0.
|
|
273
|
+
rubygems_version: 4.0.18
|
|
274
274
|
specification_version: 4
|
|
275
275
|
summary: Opensearch output plugin for Fluent event collector
|
|
276
276
|
test_files:
|