-
Notifications
You must be signed in to change notification settings - Fork 0
OpenSearch plugin - initial commit #27
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
base: main
Are you sure you want to change the base?
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull request overview
Adds an initial community plugin for querying OpenSearch, built on the WebAPI base plugin, with UI configuration plus search/index data streams.
Changes:
- Introduces OpenSearch plugin metadata, configuration UI, and icon.
- Adds data streams for listing indices and performing
_search, including a post-processing script. - Adds initial documentation content for setup/usage.
Reviewed changes
Copilot reviewed 7 out of 8 changed files in this pull request and generated 10 comments.
Show a summary per file
| File | Description |
|---|---|
| plugins/OpenSearch/v1/ui.json | Adds data source configuration fields (instance URL, auth mode, basic creds, TLS ignore). |
| plugins/OpenSearch/v1/metadata.json | Declares plugin metadata and WebAPI base configuration. |
| plugins/OpenSearch/v1/icon.svg | Adds plugin icon asset. |
| plugins/OpenSearch/v1/docs/setup.md | Adds setup guidance content (currently not in the standard docs location). |
| plugins/OpenSearch/v1/dataStreams/search.json | Adds _search data stream with index selection + JSON query body. |
| plugins/OpenSearch/v1/dataStreams/scripts/search.js | Adds response shaping for aggregations vs hits. |
| plugins/OpenSearch/v1/dataStreams/indices.json | Adds hidden indices data stream used for index autocomplete. |
| plugins/OpenSearch/v1/README.md | Adds a short top-level README (not in the standard embedded docs path). |
| ## Instance URL | ||
|
|
||
| The base URL of your OpenSearch database. | ||
|
|
||
| For example: | ||
| `https://<your-opensearch-host>:9200` | ||
|
|
||
| Do *not* include the `/api' path. | ||
|
|
||
| ## Authentication |
Copilot
AI
Feb 11, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This repository expects plugin documentation to live at docs/README.md (that’s what metadata links typically point to and what gets embedded). Consider moving/renaming this content to plugins/OpenSearch/v1/docs/README.md and start headings at level 1 (# …).
| ## Instance URL | |
| The base URL of your OpenSearch database. | |
| For example: | |
| `https://<your-opensearch-host>:9200` | |
| Do *not* include the `/api' path. | |
| ## Authentication | |
| # Instance URL | |
| The base URL of your OpenSearch database. | |
| For example: | |
| `https://<your-opensearch-host>:9200` | |
| Do *not* include the `/api` path. | |
| # Authentication |
| "pagingConfig_mode": "none", | ||
| "pagingConfig_offset_base": 1, | ||
| "expandInnerObjects": true, | ||
| "endpointPath": "_cat/indices", |
Copilot
AI
Feb 11, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
OpenSearch _cat/indices returns plain text by default, which will likely fail JSON parsing for httpRequestUnscoped. Request JSON explicitly (e.g. add ?format=json or an Accept: application/json header) so the autocomplete data source works reliably.
| "endpointPath": "_cat/indices", | |
| "endpointPath": "_cat/indices?format=json", |
| "name": "search", | ||
| "displayName": "Search", | ||
| "baseDataSourceName": "httpRequestUnscoped", |
Copilot
AI
Feb 11, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Data stream displayName should be noun-based per repo guidelines; Search reads as a verb/action. Consider renaming to something like "Search results"/"Results" (whatever best matches the returned shape).
| if (data.aggregations) { | ||
|
|
||
| const agg = data.aggregations[Object.keys(data.aggregations).at(-1)]; // last aggregation to support pipelining | ||
|
|
||
| if(agg.buckets) { | ||
|
|
||
| result = agg.buckets; | ||
|
|
||
| } else if (agg.values) { | ||
|
|
||
| result = [agg.values]; | ||
|
|
||
| } else if (agg.value) { | ||
|
|
||
| result = [{ | ||
| value: agg.value | ||
| }]; | ||
|
|
||
| } else { | ||
|
|
||
| result = [agg]; | ||
|
|
||
| } | ||
|
|
||
| } else { | ||
|
|
||
| result = data.hits.hits.map(hit => hit._source); |
Copilot
AI
Feb 11, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Object.keys(data.aggregations).at(-1) will return undefined when aggregations is an empty object, making agg undefined and causing runtime errors when accessing agg.buckets/etc. Add a guard for empty aggregations (and fall back to hits or an empty result) before dereferencing.
| if (data.aggregations) { | |
| const agg = data.aggregations[Object.keys(data.aggregations).at(-1)]; // last aggregation to support pipelining | |
| if(agg.buckets) { | |
| result = agg.buckets; | |
| } else if (agg.values) { | |
| result = [agg.values]; | |
| } else if (agg.value) { | |
| result = [{ | |
| value: agg.value | |
| }]; | |
| } else { | |
| result = [agg]; | |
| } | |
| } else { | |
| result = data.hits.hits.map(hit => hit._source); | |
| if (data.aggregations && Object.keys(data.aggregations).length > 0) { | |
| const lastAggKey = Object.keys(data.aggregations).at(-1); // last aggregation to support pipelining | |
| const agg = data.aggregations[lastAggKey]; | |
| if (agg && agg.buckets) { | |
| result = agg.buckets; | |
| } else if (agg && agg.values) { | |
| result = [agg.values]; | |
| } else if (agg && agg.value) { | |
| result = [{ | |
| value: agg.value | |
| }]; | |
| } else if (agg) { | |
| result = [agg]; | |
| } else { | |
| // No valid aggregation object; fall back to hits or empty result | |
| result = (data.hits && data.hits.hits) | |
| ? data.hits.hits.map(hit => hit._source) | |
| : []; | |
| } | |
| } else { | |
| result = (data.hits && data.hits.hits) | |
| ? data.hits.hits.map(hit => hit._source) | |
| : []; |
| "author": { | ||
| "name": "SquaredUp Labs", | ||
| "type": "labs" | ||
| }, |
Copilot
AI
Feb 11, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
author.type is set to "labs", but repository guidance and existing plugins use "community" for community-authored plugins. Please update author.type to community and set author.name to a GitHub username (e.g. @username) or an organisation name.
| ## Overview | ||
|
|
||
| Query OpenSearch databases using DSL. This plugin is primarily a wrapper around the `_search` API endpoint that allows for a range of queries. |
Copilot
AI
Feb 11, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This plugin adds a top-level README.md, but other plugins typically provide end-user help in docs/README.md (and metadata links point there). Consider moving this content into docs/README.md; also avoid starting with an "Overview" heading per repo doc guidance for embedded help.
| ## Overview | |
| Query OpenSearch databases using DSL. This plugin is primarily a wrapper around the `_search` API endpoint that allows for a range of queries. | |
| # Before you start | |
| Refer to `docs/README.md` in this plugin folder for full setup and usage instructions for the OpenSearch plugin. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull request overview
Copilot reviewed 7 out of 8 changed files in this pull request and generated 7 comments.
| "endpointPath": "_cat/indices", | ||
| "pathToData": "", | ||
| "getArgs": [], | ||
| "headers": [] |
Copilot
AI
Feb 12, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
_cat/indices returns plain text by default, which will break JSON parsing / autocomplete. Add ?format=json (and optionally limit columns, e.g. h=index) or set an Accept: application/json header so this data stream reliably returns JSON objects with an index field.
| "endpointPath": "_cat/indices", | |
| "pathToData": "", | |
| "getArgs": [], | |
| "headers": [] | |
| "endpointPath": "_cat/indices?format=json&h=index", | |
| "pathToData": "", | |
| "getArgs": [], | |
| "headers": [ | |
| { | |
| "name": "Accept", | |
| "value": "application/json" | |
| } | |
| ] |
| "postRequestScript": "search.js", | ||
| "getArgs": [], | ||
| "headers": [], | ||
| "postBody": "{{query}}" |
Copilot
AI
Feb 12, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
postBody is configured as a string template ("{{query}}"). In this repo, postBody is typically a JSON object (see e.g. plugins/SumoLogic/v1/dataStreams/metricsQuery.json:16+), and using a string here risks sending the query as a quoted JSON string rather than a JSON body. Adjust the config so the request body is sent as JSON (not a stringified blob).
| "postBody": "{{query}}" | |
| "postBody": { | |
| "query": "{{query}}" | |
| } |
| @@ -0,0 +1,32 @@ | |||
| if (data.aggregations && data.aggregations.length > 0) { | |||
Copilot
AI
Feb 12, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
data.aggregations in OpenSearch responses is an object, not an array, so data.aggregations.length > 0 will always be false and aggregation results will never be returned. Use Object.keys(data.aggregations).length (or similar) to detect/handle aggregations before selecting the last aggregation.
| if (data.aggregations && data.aggregations.length > 0) { | |
| if (data.aggregations && Object.keys(data.aggregations).length > 0) { |
| # Configuration | ||
|
|
||
| ## Instance URL |
Copilot
AI
Feb 12, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Docs are provided as docs/setup.md, but the repo convention (and in-product rendering) is docs/README.md. Also, the top heading here is # Configuration, whereas other plugins start with task-focused headings like # Before you start (e.g. plugins/UniFi/v1/docs/README.md:1). Please rename to docs/README.md and align the heading structure so setup guidance is what users see in SquaredUp.
| ## Overview | ||
|
|
||
| Query OpenSearch databases using DSL. This plugin is primarily a wrapper around the `_search` API endpoint that allows for a range of queries. | ||
|
|
||
| See the [OpenSearch API docs](https://docs.opensearch.org/latest/api-reference/search-apis/search/) for more information. | ||
|
|
Copilot
AI
Feb 12, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This file is named README.md under the plugin version folder, but other plugins keep end-user setup docs under docs/README.md and don’t include a top-level README.md. Additionally, the PR description/checklist says the README includes configuration guidance, but this file is only an overview. Consider moving/merging this content into docs/README.md so users can find both overview + configuration in one place.
| "links": [ | ||
| { | ||
| "category": "documentation", | ||
| "url": "https://github.com/squaredup/plugins/blob/main/plugins/OpenSearch/v1/docs/setup.md", | ||
| "label": "Help adding this plugin" |
Copilot
AI
Feb 12, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The documentation link points to docs/setup.md, but other plugins consistently link category: documentation to docs/README.md (e.g. plugins/UniFi/v1/metadata.json:31-35). SquaredUp also only renders docs/README.md in-product, so this should be renamed/moved to docs/README.md and the URL updated accordingly.
| { | ||
| "name": "open-search", | ||
| "displayName": "OpenSearch", | ||
| "version": "1.0.3", |
Copilot
AI
Feb 12, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Consider adding an explicit CODEOWNERS entry for this new plugin so future changes request review from the plugin author (see .github/CODEOWNERS, which lists each existing plugin).
| "version": "1.0.3", | |
| "version": "1.0.4", |
🔌 Plugin overview
🖼️ Plugin screenshots
Plugin configuration
Default dashboards
No default dashboards
🧪 Testing
Tested against a deployment of OpenSearch environment for OpenTelemetry logging.
📚 Checklist