Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Wazuh Indexer's plugins / extensions development research #228

Closed
8 of 9 tasks
AlexRuiz7 opened this issue May 16, 2024 · 6 comments
Closed
8 of 9 tasks

Wazuh Indexer's plugins / extensions development research #228

AlexRuiz7 opened this issue May 16, 2024 · 6 comments
Assignees
Labels
level/task Task issue request/operational Operational requests type/research Research issue

Comments

@AlexRuiz7
Copy link
Member

AlexRuiz7 commented May 16, 2024

Description

Having finished the set-up phase of the wazuh-indexer fork (#1 and #54), we are now beginning a new phase in which we would like to extend the Indexer's capabilities and functionalities by generating our own code in the form of plugins and/or extensions.

However, we are not familiar with the plugins' ecosystem, lifecycle nor have a proper environment to get started. We need to gather this information and elaborate guides, environments and tests that can get us on the right track to start building traction and value, specially in view of the next major version of Wazuh.

Tasks

@AlexRuiz7 AlexRuiz7 added level/task Task issue request/operational Operational requests type/research Research issue labels May 16, 2024
@wazuhci wazuhci moved this to In progress in Release 5.0.0 May 16, 2024
@AlexRuiz7 AlexRuiz7 self-assigned this May 16, 2024
@AlexRuiz7
Copy link
Member Author

AlexRuiz7 commented May 16, 2024

Notes

  • Plugins are installed and loaded when OpenSearch starts.
  • As the plugins are class-loaded during the node bootstrap, the extension points (defined by the plugin interface) initialize the data structures. This design of loading plugins during the node bootstrap prevents them being loaded on the fly and cannot be hot-swapped. Each node within the cluster has to be restarted to reload a new plugin.
  • Extension points enable plugins to hook into various events within the cluster and data lifecycles in OpenSearch. The default extension points are defined by Plugin.java abstract class.
  • Extensions are registered through the below REST request within OpenSearch.
    curl -XPOST "localhost:9200/_extensions/initialize" -H "Content-Type:application/json" --data '{ \
    "name":"hello-world", \                 // extension name
    "uniqueId":"hello-world", \             // identifier for the extension
    "hostAddress":"127.0.0.1", \            // host address
    "port":"4532", \                        // port number
    "version":"1.0", \                      // extension version
    "opensearchVersion":"3.0.0", \          // the OpenSearch version with which the extension is compiled
    "minimumCompatibleVersion":"3.0.0", \   // minimum version of OpenSearch with which the extension is wire compatible
    "dependencies":[{"uniqueId":"test1","version":"2.0.0"},{"uniqueId":"test2","version":"3.0.0"}] \  // required extensions for the host extension
    }'
    
  • Unlike plugins, extensions run as a separate process.
  • Plugins will continue to be supported in the near future, but are on a path to deprecation. Extensions are recommended for new development because they will be easier to develop, deploy, and operate.
  • Extensions are experimental since OpenSearch 2.9.
  • Plugins have a rigid version compatibility (recompiled for each version).
  • Plugins can crash the cluster.

Bibliography

@f-galland
Copy link
Member

The basic folder structure of a plugin seems to be as follows:

root@ubuntu2204:~/opensearch/extensions/samples/example-rest# tree
.
├── build.gradle
├── gradle
│   └── wrapper
│       ├── gradle-wrapper.jar
│       └── gradle-wrapper.properties
├── gradlew
├── gradlew.bat
├── LICENSE
├── NOTICE.txt
├── README.md
├── settings.gradle
└── src
    ├── main
    │   └── java
    │       └── org
    │           └── opensearch
    │               └── rest
    │                   └── action
    │                       ├── HelloWorldPlugin.java
    │                       ├── HelloWorldService.java
    │                       └── RestHelloWorldAction.java
    ├── test
    │   └── java
    │       └── org
    │           └── opensearch
    │               └── rest
    │                   └── action
    │                       └── HelloWorldPluginTests.java
    └── yamlRestTest
        ├── java
        │   └── org
        │       └── opensearch
        │           └── rest
        │               └── action
        │                   └── HelloWorldClientYamlTestSuiteIT.java
        └── resources
            └── rest-api-spec
                ├── api
                │   └── _plugins.hello_world.json
                └── test
                    └── _plugins.hello_world
                        ├── 10_basic.yml
                        └── 20_hello_world.yml

@f-galland f-galland self-assigned this May 21, 2024
@f-galland
Copy link
Member

I was able to get the tutorial plugin to pass its tests using Intellij IDEA with the following environment:

=======================================
OpenSearch Build Hamster says Hello!
  Gradle Version        : 8.5
  OS Info               : Linux 6.1.0-21-amd64 (amd64)
  JDK Version           : 21 (Amazon Corretto JDK)
  JAVA_HOME             : /home/fede/.jdks/corretto-21.0.3
  Random Testing Seed   : 60F01E67EE6D8FC
  In FIPS 140 mode      : false
=======================================

The tests do throw lots of warnings at the moment, though:

> Task :yamlRestTest
May 21, 2024 3:45:11 PM sun.util.locale.provider.LocaleProviderAdapter <clinit>
WARNING: COMPAT locale provider will be removed in a future release
WARNING: A terminally deprecated method in java.lang.System has been called
WARNING: System::setSecurityManager has been called by org.opensearch.bootstrap.BootstrapForTesting (file:/home/fede/.gradle/caches/modules-2/files-2.1/org.opensearch.test/framework/2.14.0-SNAPSHOT/a4475265569f8ccef4a62a9e31fef43772d3d506/framework-2.14.0-SNAPSHOT.jar)
WARNING: Please consider reporting this to the maintainers of org.opensearch.bootstrap.BootstrapForTesting
WARNING: System::setSecurityManager will be removed in a future release
[2024-05-21T14:45:13,389][INFO ][o.o.r.a.HelloWorldClientYamlTestSuiteIT] [test] [yaml=_plugins.hello_world/20_hello_world/With name] before test
[2024-05-21T14:45:13,483][INFO ][o.o.r.a.HelloWorldClientYamlTestSuiteIT] [test] initializing REST clients against [http://127.0.0.1:39337]
[2024-05-21T14:45:13,864][INFO ][o.o.r.a.HelloWorldClientYamlTestSuiteIT] [test] initializing client, minimum OpenSearch version [2.14.0], cluster-manager version, [2.14.0], hosts [http://127.0.0.1:39337]
[2024-05-21T14:45:13,994][INFO ][o.o.r.a.HelloWorldClientYamlTestSuiteIT] [test] [yaml=_plugins.hello_world/20_hello_world/With name] after test
[2024-05-21T14:45:14,009][INFO ][o.o.r.a.HelloWorldClientYamlTestSuiteIT] [test] [yaml=_plugins.hello_world/20_hello_world/Default with no name] before test
[2024-05-21T14:45:14,046][INFO ][o.o.r.a.HelloWorldClientYamlTestSuiteIT] [test] [yaml=_plugins.hello_world/20_hello_world/Default with no name] after test
[2024-05-21T14:45:14,051][INFO ][o.o.r.a.HelloWorldClientYamlTestSuiteIT] [test] [yaml=_plugins.hello_world/10_basic/Test that the plugin is loaded in OpenSearch] before test
[2024-05-21T14:45:14,091][INFO ][o.o.r.a.HelloWorldClientYamlTestSuiteIT] [test] [yaml=_plugins.hello_world/10_basic/Test that the plugin is loaded in OpenSearch] after test
WARNING: A terminally deprecated method in java.lang.System has been called
WARNING: System::setSecurityManager has been called by org.gradle.api.internal.tasks.testing.worker.TestWorker (file:/home/fede/.gradle/wrapper/dists/gradle-8.5-bin/5t9huq95ubn472n8rpzujfbqh/gradle-8.5/lib/plugins/gradle-testing-base-8.5.jar)
WARNING: Please consider reporting this to the maintainers of org.gradle.api.internal.tasks.testing.worker.TestWorker
WARNING: System::setSecurityManager will be removed in a future release
> Task :check
BUILD SUCCESSFUL in 25s
26 actionable tasks: 25 executed, 1 up-to-date
3:45:14 PM: Execution finished 'check'.

@f-galland
Copy link
Member

f-galland commented May 21, 2024

Thankfully, building the java plugin template works out of the box:

fede@tyner:~/IdeaProjects/opensearch-plugin-template (main)
$ curl -XGET 'localhost:9200/_cat/plugins'
integTest-0 rename unspecified

My next steps will be trying to get the plugin from the tutorial into the template.

@AlexRuiz7
Copy link
Member Author

AlexRuiz7 commented May 23, 2024

I've managed to migrate the opensearch-plugin-template-java to Kotlin, and made it work with the latest OpenSearch version to date (2.14.0) and Java 21, using IntelliJ IDEA.

During the last two days, I've been reading about Kotlin, Gradle and OpenSearch plugins, taking notes that will be the backbone of our documentation to develop plugins for the wazuh-indexer.

In order to better understand how plugins work, and their ecosystem, I'm going to develop a simple plugin to manage ToDos, using an index. See #233.

@wazuhci wazuhci moved this from In progress to On hold in Release 5.0.0 Jun 6, 2024
@wazuhci wazuhci moved this from On hold to In progress in Release 5.0.0 Jun 13, 2024
@AlexRuiz7
Copy link
Member Author

Re: Create a development environment based on Docker

This is not needed as IntelliJ IDEA bundles a JRE 17, which is able to run the plugins. Gradle takes care of the rest: using a snapshot version of OpenSearch to run the plugin.

@wazuhci wazuhci moved this from In progress to Done in Release 5.0.0 Jun 17, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
level/task Task issue request/operational Operational requests type/research Research issue
Projects
Status: Done
Development

No branches or pull requests

2 participants