logstash-output-opensearch 1.3.0-java → 2.0.3-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 (32) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +0 -0
  3. data/COMPATIBILITY.md +5 -3
  4. data/DEVELOPER_GUIDE.md +6 -1
  5. data/MAINTAINERS.md +15 -64
  6. data/README.md +57 -35
  7. data/RELEASING.md +5 -1
  8. data/docs/building_custom_docker_images.md +79 -0
  9. data/docs/ecs_compatibility.md +42 -0
  10. data/lib/logstash/outputs/opensearch/http_client/manticore_adapter.rb +47 -14
  11. data/lib/logstash/outputs/opensearch/http_client/pool.rb +11 -2
  12. data/lib/logstash/outputs/opensearch/http_client.rb +28 -6
  13. data/lib/logstash/outputs/opensearch/http_client_builder.rb +4 -2
  14. data/lib/logstash/outputs/opensearch/template_manager.rb +6 -5
  15. data/lib/logstash/outputs/opensearch/templates/ecs-disabled/1x_index.json +66 -0
  16. data/lib/logstash/outputs/opensearch/templates/ecs-disabled/2x_index.json +66 -0
  17. data/lib/logstash/outputs/opensearch/templates/ecs-disabled/7x_index.json +66 -0
  18. data/lib/logstash/outputs/opensearch/templates/ecs-v8/1x_index.json +5254 -0
  19. data/lib/logstash/outputs/opensearch/templates/ecs-v8/2x_index.json +5254 -0
  20. data/lib/logstash/outputs/opensearch/templates/ecs-v8/7x_index.json +5254 -0
  21. data/lib/logstash/outputs/opensearch.rb +7 -0
  22. data/lib/logstash/plugin_mixins/opensearch/common.rb +1 -0
  23. data/logstash-output-opensearch.gemspec +2 -2
  24. data/spec/integration/outputs/index_spec.rb +3 -2
  25. data/spec/opensearch_spec_helper.rb +9 -0
  26. data/spec/unit/outputs/opensearch/http_client/manticore_adapter_spec.rb +72 -14
  27. data/spec/unit/outputs/opensearch/http_client_spec.rb +20 -0
  28. data/spec/unit/outputs/opensearch/template_manager_spec.rb +8 -20
  29. data/spec/unit/outputs/opensearch_spec.rb +24 -0
  30. data.tar.gz.sig +0 -0
  31. metadata +32 -30
  32. 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: c4d023016ab9043a845b0c4c35fc0fea899235e8f15d32f8cc9799a29dd4a84a
4
+ data.tar.gz: 1eef3e646ab7a2ec0ac175fa26b3fe7983755133de4bb0580ea55299d55ce18c
5
5
  SHA512:
6
- metadata.gz: ed114d31a8dd15ebe57cba0d87c278efe3be2a47743aa2cdfe99bf861e0934edb2772d09aa59eda0d9428b119dde77a16c82371ce19ca1cbfb5c6ce736692690
7
- data.tar.gz: df6263f5109d5834bc19fa9804c082c95dc1867eed7926be99b7682c4c1cfb3abffa0ff23b16f123f55f196e353527d31d8d5a61f3011bbf56805f43fa890fdc
6
+ metadata.gz: e22c44f48115c0df680dc9dc1e886daa5ac1521daf1a3b1ee3c9f5574eed59e7974356bff2055dfc44c0ed01115cb8838b073ffa7b81d70172b5da227c718584
7
+ data.tar.gz: 98556ece3e0e8f771a8168bffb32d6b8be5d4e21d356cbd64ddb814b26ac5cb91c3b58a94f49dec72e377a67cb3896008a7441f9db2373bcf3c15de9f7ece2a9
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/DEVELOPER_GUIDE.md CHANGED
@@ -9,6 +9,7 @@
9
9
  - [Configuration for Logstash Output OpenSearch Plugin](#configuration-for-logstash-output-opensearch-plugin)
10
10
  - [Submitting Changes](#submitting-changes)
11
11
  - [Backports](#backports)
12
+ - [Building Custom Docker Images](docs/building_custom_docker_images.md)
12
13
 
13
14
  # Developer Guide
14
15
 
@@ -185,13 +186,14 @@ Build the gem locally and install it using:
185
186
  ## Configuration for Logstash Output OpenSearch Plugin
186
187
 
187
188
  To run the Logstash Output Opensearch plugin, add following configuration in your logstash.conf file.
189
+ Note: For logstash running with OpenSearch 2.12.0 and higher the admin password needs to be a custom strong password supplied during cluster setup.
188
190
 
189
191
  ```
190
192
  output {
191
193
  opensearch {
192
194
  hosts => ["hostname:port"]
193
195
  user => "admin"
194
- password => "admin"
196
+ password => "<your-admin-password>"
195
197
  index => "logstash-logs-%{+YYYY.MM.dd}"
196
198
  }
197
199
  }
@@ -215,3 +217,6 @@ original PR with an appropriate label `backport <backport-branch-name>` is merge
215
217
  run successfully on the PR. For example, if a PR on main needs to be backported to `1.x` branch, add a label
216
218
  `backport 1.x` to the PR and make sure the backport workflow runs on the PR along with other checks. Once this PR is
217
219
  merged to main, the workflow will create a backport PR to the `1.x` branch.
220
+
221
+ # [Building Custom Docker Images](docs/building_custom_docker_images.md)
222
+
data/MAINTAINERS.md CHANGED
@@ -1,74 +1,25 @@
1
- - [Overview](#overview)
2
- - [Current Maintainers](#current-maintainers)
3
- - [Maintainer Responsibilities](#maintainer-responsibilities)
4
- - [Uphold Code of Conduct](#uphold-code-of-conduct)
5
- - [Prioritize Security](#prioritize-security)
6
- - [Review Pull Requests](#review-pull-requests)
7
- - [Triage Open Issues](#triage-open-issues)
8
- - [Be Responsive](#be-responsive)
9
- - [Maintain Overall Health of the Repo](#maintain-overall-health-of-the-repo)
10
- - [Use Semver](#use-semver)
11
- - [Release Frequently](#release-frequently)
12
- - [Promote Other Maintainers](#promote-other-maintainers)
13
-
14
1
  ## Overview
15
2
 
16
- This document explains who the maintainers are (see below), what they do in this repo, and how they should be doing it. If you're interested in contributing, see [CONTRIBUTING](CONTRIBUTING.md).
3
+ This document contains a list of maintainers in this repo. See [opensearch-project/.github/RESPONSIBILITIES.md](https://github.com/opensearch-project/.github/blob/main/RESPONSIBILITIES.md#maintainer-responsibilities) that explains what the role of maintainer means, what maintainers do in this and other repos, and how they should be doing it. If you're interested in contributing, and becoming a maintainer, see [CONTRIBUTING](CONTRIBUTING.md).
17
4
 
18
5
  ## Current Maintainers
19
6
 
20
- | Maintainer | GitHub ID | Affiliation |
21
- | ------------------------ | --------------------------------------- | ----------- |
22
- | Jack Mazanec | [jmazanec15](https://github.com/jmazanec15) | Amazon |
23
- | Vamshi Vijay Nakkirtha | [vamshin](https://github.com/vamshin) | Amazon |
24
- | Vijayan Balasubramanian | [VijayanB](https://github.com/VijayanB) | Amazon |
25
- | Deep Datta | [deepdatta](https://github.com/deepdatta) | Amazon |
26
- | David Venable | [dlvenable](https://github.com/dlvenable) | Amazon |
27
- | Shivani Shukla | [sshivanii](https://github.com/sshivanii) | Amazon |
28
-
29
- ## Maintainer Responsibilities
30
-
31
- Maintainers are active and visible members of the community, and have [maintain-level permissions on a repository](https://docs.github.com/en/organizations/managing-access-to-your-organizations-repositories/repository-permission-levels-for-an-organization). Use those privileges to serve the community and evolve code as follows.
32
-
33
- ### Uphold Code of Conduct
34
-
35
- Model the behavior set forward by the [Code of Conduct](CODE_OF_CONDUCT.md) and raise any violations to other maintainers and admins.
36
-
37
- ### Prioritize Security
38
-
39
- Security is your number one priority. Maintainer's Github keys must be password protected securely and any reported security vulnerabilities are addressed before features or bugs.
40
-
41
- Note that this repository is monitored and supported 24/7 by Amazon Security, see [Reporting a Vulnerability](SECURITY.md) for details.
42
-
43
- ### Review Pull Requests
44
-
45
- Review pull requests regularly, comment, suggest, reject, merge and close. Accept only high quality pull-requests. Provide code reviews and guidance on incomming pull requests. Don't let PRs be stale and do your best to be helpful to contributors.
46
-
47
- ### Triage Open Issues
48
-
49
- Manage labels, review issues regularly, and triage by labelling them.
50
-
51
- All repositories in this organization have a standard set of labels, including `bug`, `documentation`, `duplicate`, `enhancement`, `good first issue`, `help wanted`, `blocker`, `invalid`, `question`, `wontfix`, and `untriaged`, along with release labels, such as `v1.0.0`, `v1.1.0` and `v2.0.0`, and `backport`.
52
-
53
- Use labels to target an issue or a PR for a given release, add `help wanted` to good issues for new community members, and `blocker` for issues that scare you or need immediate attention. Request for more information from a submitter if an issue is not clear. Create new labels as needed by the project.
54
-
55
- ### Be Responsive
56
-
57
- Respond to enhancement requests, and forum posts. Allocate time to reviewing and commenting on issues and conversations as they come in.
58
-
59
- ### Maintain Overall Health of the Repo
60
-
61
- Keep the `main` branch at production quality at all times. Backport features as needed. Cut release branches and tags to enable future patches.
62
-
63
- ### Use Semver
64
-
65
- Use and enforce [semantic versioning](https://semver.org/) and do not let breaking changes be made outside of major releases.
66
7
 
67
- ### Release Frequently
8
+ | Maintainer | GitHub ID | Affiliation |
9
+ | ------------------------ | --------------------------------------------------- | ----------- |
10
+ | Daniel "dB." Doubrovkine | [dblock](https://github.com/dblock) | Amazon |
11
+ | Asif Sohail Mohammed | [asifsmohammed](https://github.com/asifsmohammed) | Amazon |
12
+ | David Venable | [dlvenable](https://github.com/dlvenable) | Amazon |
13
+ | Hai Yan | [oeyh](https://github.com/oeyh) | Amazon |
68
14
 
69
- Make frequent project releases to the community.
70
15
 
71
- ### Promote Other Maintainers
72
16
 
73
- Assist, add, and remove [MAINTAINERS](MAINTAINERS.md). Exercise good judgement, and propose high quality contributors to become co-maintainers.
17
+ ## Emeritus
74
18
 
19
+ | Maintainer | GitHub ID | Affiliation |
20
+ | ----------------------- | ------------------------------------------- | ----------- |
21
+ | Jack Mazanec | [jmazanec15](https://github.com/jmazanec15) | Amazon |
22
+ | Vamshi Vijay Nakkirtha | [vamshin](https://github.com/vamshin) | Amazon |
23
+ | Vijayan Balasubramanian | [VijayanB](https://github.com/VijayanB) | Amazon |
24
+ | Deep Datta | [deepdatta](https://github.com/deepdatta) | Amazon |
25
+ | Shivani Shukla | [sshivanii](https://github.com/sshivanii) | Amazon |
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/tools/logstash/ship-to-opensearch/)
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)
@@ -31,12 +32,14 @@ The logstash-output-opensearch plugin helps to ship events from Logstash to Open
31
32
  ## Configuration for Logstash Output Opensearch Plugin
32
33
 
33
34
  To run the Logstash Output Opensearch plugin, add following configuration in your logstash.conf file.
35
+ Note: For logstash running with OpenSearch 2.12.0 and higher the admin password needs to be a custom strong password supplied during cluster setup.
36
+
34
37
  ```
35
38
  output {
36
39
  opensearch {
37
40
  hosts => ["hostname:port"]
38
41
  user => "admin"
39
- password => "admin"
42
+ password => "<your-admin-password>"
40
43
  index => "logstash-logs-%{+YYYY.MM.dd}"
41
44
  }
42
45
  }
@@ -44,55 +47,74 @@ output {
44
47
 
45
48
  To run the Logstash Output Opensearch plugin using aws_iam authentication, refer to the sample configuration shown below:
46
49
  ```
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
- }
50
+ output {
51
+ opensearch {
52
+ hosts => ["hostname:port"]
53
+ auth_type => {
54
+ type => 'aws_iam'
55
+ aws_access_key_id => 'ACCESS_KEY'
56
+ aws_secret_access_key => 'SECRET_KEY'
57
+ region => 'us-west-2'
58
+ }
59
+ index => "logstash-logs-%{+YYYY.MM.dd}"
60
+ }
58
61
  }
59
62
  ```
60
63
 
61
64
  In addition to the existing authentication mechanisms, if we want to add new authentication then we will be adding them in the configuration by using auth_type.
62
65
 
63
66
  Example Configuration for basic authentication:
67
+ Note: For logstash running with OpenSearch 2.12.0 and higher the admin password needs to be a custom strong password supplied during cluster setup.
68
+
64
69
  ```
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
- }
70
+ output {
71
+ opensearch {
72
+ hosts => ["hostname:port"]
73
+ auth_type => {
74
+ type => 'basic'
75
+ user => 'admin'
76
+ password => '<your-admin-password>'
77
+ }
78
+ index => "logstash-logs-%{+YYYY.MM.dd}"
79
+ }
80
+ }
76
81
  ```
77
82
 
78
83
  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:
84
+ Note: For logstash running with OpenSearch 2.12.0 and higher the admin password needs to be a custom strong password supplied during cluster setup.
79
85
 
80
86
  ```yml
81
- output {
82
- opensearch {
83
- hosts => ["https://hostname:port"]
84
- auth_type => {
85
- type => 'basic'
86
- user => 'admin'
87
- password => 'admin'
87
+ output {
88
+ opensearch {
89
+ hosts => ["https://hostname:port"]
90
+ auth_type => {
91
+ type => 'basic'
92
+ user => 'admin'
93
+ password => '<your-admin-password>'
88
94
  }
89
95
  index => "my-data-stream"
90
96
  action => "create"
91
- }
92
- }
97
+ }
98
+ }
99
+ ```
100
+
101
+ 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
102
+ ```
103
+ # Remove existing logstash aws plugins and install logstash-integration-aws to keep sdk dependency the same
104
+ # https://github.com/logstash-plugins/logstash-mixin-aws/issues/38
105
+ /usr/share/logstash/bin/logstash-plugin remove logstash-input-s3
106
+ /usr/share/logstash/bin/logstash-plugin remove logstash-input-sqs
107
+ /usr/share/logstash/bin/logstash-plugin remove logstash-output-s3
108
+ /usr/share/logstash/bin/logstash-plugin remove logstash-output-sns
109
+ /usr/share/logstash/bin/logstash-plugin remove logstash-output-sqs
110
+ /usr/share/logstash/bin/logstash-plugin remove logstash-output-cloudwatch
111
+
112
+ /usr/share/logstash/bin/logstash-plugin install --version 0.1.0.pre logstash-integration-aws
113
+ /usr/share/logstash/bin/logstash-plugin install --version 2.0.0 logstash-output-opensearch
93
114
  ```
115
+ ## ECS Compatibility
116
+ [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
117
 
95
- For more details refer to this [documentation](https://opensearch.org/docs/latest/clients/logstash/ship-to-opensearch/#opensearch-output-plugin)
96
118
 
97
119
  ## Code of Conduct
98
120
 
@@ -104,4 +126,4 @@ This project is licensed under the [Apache v2.0 License](LICENSE).
104
126
 
105
127
  ## Copyright
106
128
 
107
- Copyright OpenSearch Contributors. See [NOTICE](NOTICE) for details.
129
+ Copyright OpenSearch Contributors. See [NOTICE](NOTICE) for details.
data/RELEASING.md CHANGED
@@ -33,4 +33,8 @@ Repositories create consistent release labels, such as `v1.0.0`, `v1.1.0` and `v
33
33
 
34
34
  The release process is standard across repositories in this org and is run by a release manager volunteering from amongst [MAINTAINERS](MAINTAINERS.md).
35
35
 
36
- TODO
36
+ 1. Create a tag, e.g. 1.0.0, and push it to this GitHub repository.
37
+ 1. The [release-drafter.yml](.github/workflows/release-drafter.yml) will be automatically kicked off and a draft release will be created.
38
+ 1. This draft release triggers the [jenkins release workflow](https://build.ci.opensearch.org/job/logstash-ouput-opensearch-release) as a As a result of which the logstash-output-plugin is released on [rubygems.org](https://rubygems.org/gems/logstash-output-opensearch). Please note that the release workflow is triggered only if created release is in draft state.
39
+ 1. Once the above release workflow is successful, the drafted release on GitHub is published automatically.
40
+ 1. Increment "version" in [logstash-output-opensearch.gemspec](./logstash-output-opensearch.gemspec) to the next iteration, e.g. 1.0.1.
@@ -0,0 +1,79 @@
1
+ - [Building Custom Docker Images](#building-custom-docker-images)
2
+ - [Logstash 8.x](#logstash-8x)
3
+ - [Logstash 7.x](#logstash-7x)
4
+ - [Build Logstash Output OpenSearch Plugin Gem](#build-logstash-output-opensearch-plugin-gem)
5
+ - [Dockerfile](#dockerfile)
6
+
7
+
8
+ # Building Custom Docker Images
9
+
10
+ To build an image that is not available in the [official Docker repository tags](https://hub.docker.com/r/opensearchproject/logstash-oss-with-opensearch-output-plugin/tags), or to add specific plugins to your image, you can create a custom Dockerfile.
11
+
12
+ The process varies depending on whether you want to build an image with `Logstash 8.x` versions or `Logstash 7.x` versions
13
+
14
+ ## Logstash 8.x
15
+
16
+ Create this `Dockerfile` to build an image with `OpenSearch 2.0.2` for **`Logstash 8.x`**
17
+
18
+ ``` Dockerfile
19
+ ARG APP_VERSION
20
+
21
+ FROM docker.elastic.co/logstash/logstash-oss:${APP_VERSION}
22
+ RUN logstash-plugin install --version 7.1.1 logstash-integration-aws
23
+ RUN logstash-plugin install --version 2.0.2 logstash-output-opensearch
24
+ ```
25
+
26
+ ## Logstash 7.x
27
+
28
+ For **`Logstash 7.x`** , the Logstash output OpenSearch gem needs to be build.
29
+
30
+ ### Build Logstash Output OpenSearch Plugin Gem
31
+
32
+ 1. Clone `logstash-output-opensearch repo`
33
+
34
+ ```sh
35
+ git clone https://github.com/opensearch-project/logstash-output-opensearch.git
36
+ ```
37
+
38
+ 2. Checkout the tag for the plugin version you want to build. For the version [2.0.2](https://github.com/opensearch-project/logstash-output-opensearch/tree/2.0.2) for example
39
+
40
+ ```sh
41
+ git checkout 2.0.2
42
+ ```
43
+
44
+
45
+ 3. Remove [this line that adds the json version spec](https://github.com/opensearch-project/logstash-output-opensearch/blob/2.0.2/logstash-output-opensearch.gemspec#L49). This version of the JSON gem is incompatible with `Logstash version 7.x`.
46
+
47
+ 4. Build the gem by running the following command:
48
+
49
+ ```sh
50
+ gem build logstash-output-opensearch.gemspec
51
+ ```
52
+
53
+ The Gemfile `logstash-output-opensearch-2.0.2-x86_64-linux.gem` will be generated.
54
+
55
+ ### Dockerfile
56
+
57
+ Create this Dockerfile to build an image with `logstash version 7.x` and the previously generated `Gemfile` :
58
+
59
+ ```Dockerfile
60
+ ARG APP_VERSION
61
+
62
+ FROM docker.elastic.co/logstash/logstash-oss:${APP_VERSION}
63
+
64
+ USER logstash
65
+ # Remove existing logstash aws plugins and install logstash-integration-aws to keep sdk dependency the same
66
+ # https://github.com/logstash-plugins/logstash-mixin-aws/issues/38
67
+ # https://github.com/opensearch-project/logstash-output-opensearch#configuration-for-logstash-output-opensearch-plugin
68
+ RUN logstash-plugin remove logstash-input-s3
69
+ RUN logstash-plugin remove logstash-input-sqs
70
+ RUN logstash-plugin remove logstash-output-s3
71
+ RUN logstash-plugin remove logstash-output-sns
72
+ RUN logstash-plugin remove logstash-output-sqs
73
+ RUN logstash-plugin remove logstash-output-cloudwatch
74
+
75
+ RUN logstash-plugin install --version 7.1.1 logstash-integration-aws
76
+
77
+ COPY logstash-output-opensearch-2.0.2-x86_64-linux.gem /usr/share
78
+ RUN logstash-plugin install /usr/share/logstash-output-opensearch-2.0.2-x86_64-linux.gem
79
+ ```
@@ -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)
@@ -12,6 +12,9 @@ require 'cgi'
12
12
  require 'manticore'
13
13
  require 'uri'
14
14
 
15
+ java_import 'org.apache.http.util.EntityUtils'
16
+ java_import 'org.apache.http.entity.StringEntity'
17
+
15
18
  module LogStash; module Outputs; class OpenSearch; class HttpClient;
16
19
  AWS_DEFAULT_PORT = 443
17
20
  AWS_DEFAULT_PROFILE = 'default'
@@ -30,7 +33,8 @@ module LogStash; module Outputs; class OpenSearch; class HttpClient;
30
33
  :profile,
31
34
  :instance_profile_credentials_retries,
32
35
  :instance_profile_credentials_timeout,
33
- :region)
36
+ :region,
37
+ :account_id)
34
38
 
35
39
  class ManticoreAdapter
36
40
  attr_reader :manticore, :logger
@@ -57,7 +61,7 @@ module LogStash; module Outputs; class OpenSearch; class HttpClient;
57
61
  if options[:proxy]
58
62
  options[:proxy] = manticore_proxy_hash(options[:proxy])
59
63
  end
60
-
64
+
61
65
  @manticore = ::Manticore::Client.new(options)
62
66
  end
63
67
 
@@ -75,9 +79,11 @@ module LogStash; module Outputs; class OpenSearch; class HttpClient;
75
79
  instance_cred_retries = options[:auth_type]["instance_profile_credentials_retries"] || AWS_DEFAULT_PROFILE_CREDENTIAL_RETRY
76
80
  instance_cred_timeout = options[:auth_type]["instance_profile_credentials_timeout"] || AWS_DEFAULT_PROFILE_CREDENTIAL_TIMEOUT
77
81
  region = options[:auth_type]["region"] || AWS_DEFAULT_REGION
82
+ account_id = nil
78
83
  set_aws_region(region)
84
+ set_service_name(options[:auth_type]["service_name"] || AWS_SERVICE)
79
85
 
80
- credential_config = AWSIAMCredential.new(aws_access_key_id, aws_secret_access_key, session_token, profile, instance_cred_retries, instance_cred_timeout, region)
86
+ credential_config = AWSIAMCredential.new(aws_access_key_id, aws_secret_access_key, session_token, profile, instance_cred_retries, instance_cred_timeout, region, account_id)
81
87
  @credentials = Aws::CredentialProviderChain.new(credential_config).resolve
82
88
  end
83
89
 
@@ -93,6 +99,14 @@ module LogStash; module Outputs; class OpenSearch; class HttpClient;
93
99
  @region
94
100
  end
95
101
 
102
+ def set_service_name(service_name)
103
+ @service_name = service_name
104
+ end
105
+
106
+ def get_service_name()
107
+ @service_name
108
+ end
109
+
96
110
  def set_user_password(options)
97
111
  @user = options[:auth_type]["user"]
98
112
  @password = options[:auth_type]["password"]
@@ -105,7 +119,7 @@ module LogStash; module Outputs; class OpenSearch; class HttpClient;
105
119
  def get_password()
106
120
  @password
107
121
  end
108
-
122
+
109
123
  # Transform the proxy option to a hash. Manticore's support for non-hash
110
124
  # proxy options is broken. This was fixed in https://github.com/cheald/manticore/commit/34a00cee57a56148629ed0a47c329181e7319af5
111
125
  # but this is not yet released
@@ -137,12 +151,12 @@ module LogStash; module Outputs; class OpenSearch; class HttpClient;
137
151
  params[:body] = body if body
138
152
 
139
153
  if url.user
140
- params[:auth] = {
154
+ params[:auth] = {
141
155
  :user => CGI.unescape(url.user),
142
156
  # We have to unescape the password here since manticore won't do it
143
157
  # for us unless its part of the URL
144
- :password => CGI.unescape(url.password),
145
- :eager => true
158
+ :password => CGI.unescape(url.password),
159
+ :eager => true
146
160
  }
147
161
  elsif @type == BASIC_AUTH_TYPE
148
162
  add_basic_auth_to_params(params)
@@ -172,13 +186,32 @@ module LogStash; module Outputs; class OpenSearch; class HttpClient;
172
186
  resp
173
187
  end
174
188
 
189
+ # from Manticore, https://github.com/cheald/manticore/blob/acc25cac2999f4658a77a0f39f60ddbca8fe14a4/lib/manticore/client.rb#L536
190
+ ISO_8859_1 = "ISO-8859-1".freeze
191
+
192
+ def minimum_encoding_for(string)
193
+ if string.ascii_only?
194
+ ISO_8859_1
195
+ else
196
+ string.encoding.to_s
197
+ end
198
+ end
199
+
175
200
  def sign_aws_request(request_uri, path, method, params)
176
201
  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)
202
+
203
+ request = Seahorse::Client::Http::Request.new(options={:endpoint=>url, :http_method => method.to_s.upcase,
204
+ :headers => params[:headers],:body => params[:body]})
205
+
206
+ aws_signer = Aws::Sigv4::Signer.new(service: @service_name, region: @region, credentials_provider: @credentials)
207
+ signed_key = aws_signer.sign_request(
208
+ http_method: request.http_method,
209
+ url: url,
210
+ headers: params[:headers],
211
+ # match encoding of the HTTP adapter, see https://github.com/opensearch-project/logstash-output-opensearch/issues/207
212
+ body: params[:body] ? EntityUtils.toString(StringEntity.new(params[:body], minimum_encoding_for(params[:body]))) : nil
213
+ )
214
+ params[:headers] = params[:headers].merge(signed_key.headers)
182
215
  end
183
216
 
184
217
  def add_basic_auth_to_params(params)
@@ -192,7 +225,7 @@ module LogStash; module Outputs; class OpenSearch; class HttpClient;
192
225
  # Returned urls from this method should be checked for double escaping.
193
226
  def format_url(url, path_and_query=nil)
194
227
  request_uri = url.clone
195
-
228
+
196
229
  # We excise auth info from the URL in case manticore itself tries to stick
197
230
  # sensitive data in a thrown exception or log data
198
231
  request_uri.user = nil
@@ -208,7 +241,7 @@ module LogStash; module Outputs; class OpenSearch; class HttpClient;
208
241
  new_query_parts = [request_uri.query, parsed_path_and_query.query].select do |part|
209
242
  part && !part.empty? # Skip empty nil and ""
210
243
  end
211
-
244
+
212
245
  request_uri.query = new_query_parts.join("&") unless new_query_parts.empty?
213
246
 
214
247
  # 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