@saishnarvekar/plugin-elastic-devtool-backend 0.1.0
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.
- package/LICENSE +13 -0
- package/README.md +81 -0
- package/dist/index.cjs.js +10 -0
- package/dist/index.cjs.js.map +1 -0
- package/dist/index.d.ts +10 -0
- package/dist/plugin.cjs.js +28 -0
- package/dist/plugin.cjs.js.map +1 -0
- package/dist/router.cjs.js +55 -0
- package/dist/router.cjs.js.map +1 -0
- package/package.json +61 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
Copyright 2026 Saish Narvekar
|
|
2
|
+
|
|
3
|
+
Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
|
+
you may not use this file except in compliance with the License.
|
|
5
|
+
You may obtain a copy of the License at
|
|
6
|
+
|
|
7
|
+
http://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
+
|
|
9
|
+
Unless required by applicable law or agreed to in writing, software
|
|
10
|
+
distributed under the License is distributed on an "AS IS" BASIS,
|
|
11
|
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
|
+
See the License for the specific language governing permissions and
|
|
13
|
+
limitations under the License.
|
package/README.md
ADDED
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
developing the plugin backend itself.
|
|
2
|
+
|
|
3
|
+
# Elastic Dev Tool Plugin for Backstage (Backend)
|
|
4
|
+
|
|
5
|
+

|
|
6
|
+
|
|
7
|
+
> [!TIP]
|
|
8
|
+
> Backend API for Elasticsearch management and query in Backstage.
|
|
9
|
+
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
## Overview
|
|
13
|
+
|
|
14
|
+
`@saishnarvekar/plugin-elastic-devtool-backend` provides the backend API and service layer for the Elastic Dev Tool plugin, enabling secure, robust Elasticsearch operations from your Backstage instance.
|
|
15
|
+
|
|
16
|
+
---
|
|
17
|
+
|
|
18
|
+
## Features
|
|
19
|
+
|
|
20
|
+
- REST API for Elasticsearch query and index management
|
|
21
|
+
- Secure proxy to your Elasticsearch cluster
|
|
22
|
+
- Cluster health and stats endpoints
|
|
23
|
+
- Built with Backstage backend best practices
|
|
24
|
+
|
|
25
|
+
---
|
|
26
|
+
|
|
27
|
+
## Installation
|
|
28
|
+
|
|
29
|
+
Add the backend plugin to your Backstage backend:
|
|
30
|
+
|
|
31
|
+
```bash
|
|
32
|
+
yarn --cwd packages/backend add @saishnarvekar/plugin-elastic-devtool-backend
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
---
|
|
36
|
+
|
|
37
|
+
## Usage
|
|
38
|
+
|
|
39
|
+
Register the plugin in your backend (e.g. in `packages/backend/src/index.ts`):
|
|
40
|
+
|
|
41
|
+
```ts
|
|
42
|
+
import { elasticDevToolPlugin } from '@saishnarvekar/plugin-elastic-devtool-backend';
|
|
43
|
+
|
|
44
|
+
const backend = createBackend();
|
|
45
|
+
// ...existing code...
|
|
46
|
+
backend.add(elasticDevToolPlugin());
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
Configure your Elasticsearch connection in `app-config.yaml`:
|
|
50
|
+
|
|
51
|
+
```yaml
|
|
52
|
+
elastic:
|
|
53
|
+
baseUrl: 'http://localhost:9200'
|
|
54
|
+
username: 'elastic' # optional
|
|
55
|
+
password: 'password' # optional
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
---
|
|
59
|
+
|
|
60
|
+
## Development
|
|
61
|
+
|
|
62
|
+
To run the backend plugin in isolation for development:
|
|
63
|
+
|
|
64
|
+
```bash
|
|
65
|
+
yarn start
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
This will launch a local backend server for rapid development and testing.
|
|
69
|
+
|
|
70
|
+
---
|
|
71
|
+
|
|
72
|
+
## Resources
|
|
73
|
+
|
|
74
|
+
- [Backstage Backend Plugins](https://backstage.io/docs/backend-system/)
|
|
75
|
+
- [Elasticsearch Node.js Client](https://www.elastic.co/guide/en/elasticsearch/client/javascript-api/current/)
|
|
76
|
+
- [Backstage Plugin Authoring](https://backstage.io/docs/plugins/)
|
|
77
|
+
|
|
78
|
+
---
|
|
79
|
+
|
|
80
|
+
> [!IMPORTANT]
|
|
81
|
+
> Use together with [`@saishnarvekar/plugin-elastic-devtool`](../elastic-devtool/) for a complete frontend + backend solution.
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.cjs.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import * as _backstage_backend_plugin_api from '@backstage/backend-plugin-api';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* elasticDevtoolPlugin backend plugin
|
|
5
|
+
*
|
|
6
|
+
* @public
|
|
7
|
+
*/
|
|
8
|
+
declare const elasticDevtoolPlugin: _backstage_backend_plugin_api.BackendFeature;
|
|
9
|
+
|
|
10
|
+
export { elasticDevtoolPlugin as default };
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var backendPluginApi = require('@backstage/backend-plugin-api');
|
|
4
|
+
var router = require('./router.cjs.js');
|
|
5
|
+
|
|
6
|
+
const elasticDevtoolPlugin = backendPluginApi.createBackendPlugin({
|
|
7
|
+
pluginId: "elastic-devtool",
|
|
8
|
+
register(env) {
|
|
9
|
+
env.registerInit({
|
|
10
|
+
deps: {
|
|
11
|
+
httpRouter: backendPluginApi.coreServices.httpRouter,
|
|
12
|
+
config: backendPluginApi.coreServices.rootConfig
|
|
13
|
+
},
|
|
14
|
+
async init({ httpRouter, config }) {
|
|
15
|
+
httpRouter.use(
|
|
16
|
+
await router.createRouter({ config })
|
|
17
|
+
);
|
|
18
|
+
httpRouter.addAuthPolicy({
|
|
19
|
+
path: "/health",
|
|
20
|
+
allow: "unauthenticated"
|
|
21
|
+
});
|
|
22
|
+
}
|
|
23
|
+
});
|
|
24
|
+
}
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
exports.elasticDevtoolPlugin = elasticDevtoolPlugin;
|
|
28
|
+
//# sourceMappingURL=plugin.cjs.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"plugin.cjs.js","sources":["../src/plugin.ts"],"sourcesContent":["import {\n coreServices,\n createBackendPlugin,\n} from '@backstage/backend-plugin-api';\nimport { createRouter } from './router';\n\n/**\n * elasticDevtoolPlugin backend plugin\n *\n * @public\n */\nexport const elasticDevtoolPlugin = createBackendPlugin({\n pluginId: 'elastic-devtool',\n register(env) {\n env.registerInit({\n deps: {\n httpRouter: coreServices.httpRouter,\n config: coreServices.rootConfig,\n },\n async init({ httpRouter, config }) {\n httpRouter.use(\n await createRouter({ config }),\n );\n httpRouter.addAuthPolicy({\n path: '/health',\n allow: 'unauthenticated',\n });\n },\n });\n },\n});\n"],"names":["createBackendPlugin","coreServices","createRouter"],"mappings":";;;;;AAWO,MAAM,uBAAuBA,oCAAA,CAAoB;AAAA,EACtD,QAAA,EAAU,iBAAA;AAAA,EACV,SAAS,GAAA,EAAK;AACZ,IAAA,GAAA,CAAI,YAAA,CAAa;AAAA,MACf,IAAA,EAAM;AAAA,QACJ,YAAYC,6BAAA,CAAa,UAAA;AAAA,QACzB,QAAQA,6BAAA,CAAa;AAAA,OACvB;AAAA,MACA,MAAM,IAAA,CAAK,EAAE,UAAA,EAAY,QAAO,EAAG;AACjC,QAAA,UAAA,CAAW,GAAA;AAAA,UACT,MAAMC,mBAAA,CAAa,EAAE,MAAA,EAAQ;AAAA,SAC/B;AACA,QAAA,UAAA,CAAW,aAAA,CAAc;AAAA,UACvB,IAAA,EAAM,SAAA;AAAA,UACN,KAAA,EAAO;AAAA,SACR,CAAA;AAAA,MACH;AAAA,KACD,CAAA;AAAA,EACH;AACF,CAAC;;;;"}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var express = require('express');
|
|
4
|
+
var Router = require('express-promise-router');
|
|
5
|
+
var elasticsearch = require('@elastic/elasticsearch');
|
|
6
|
+
|
|
7
|
+
function _interopDefaultCompat (e) { return e && typeof e === 'object' && 'default' in e ? e : { default: e }; }
|
|
8
|
+
|
|
9
|
+
var express__default = /*#__PURE__*/_interopDefaultCompat(express);
|
|
10
|
+
var Router__default = /*#__PURE__*/_interopDefaultCompat(Router);
|
|
11
|
+
|
|
12
|
+
async function createRouter(options) {
|
|
13
|
+
const router = Router__default.default();
|
|
14
|
+
router.use(express__default.default.json());
|
|
15
|
+
const esNode = options.config.getString("elastic-devtool.elasticsearch.node");
|
|
16
|
+
const esUsername = options.config.getString("elastic-devtool.elasticsearch.username");
|
|
17
|
+
const esPassword = options.config.getString("elastic-devtool.elasticsearch.password");
|
|
18
|
+
const esClient = new elasticsearch.Client({
|
|
19
|
+
node: esNode,
|
|
20
|
+
auth: {
|
|
21
|
+
username: esUsername,
|
|
22
|
+
password: esPassword
|
|
23
|
+
},
|
|
24
|
+
tls: {
|
|
25
|
+
rejectUnauthorized: false
|
|
26
|
+
}
|
|
27
|
+
});
|
|
28
|
+
router.get("/health", async (_, res) => {
|
|
29
|
+
res.json({ status: "ok" });
|
|
30
|
+
});
|
|
31
|
+
router.get("/indices", async (_, res) => {
|
|
32
|
+
try {
|
|
33
|
+
const result = await esClient.cat.indices({ format: "json" });
|
|
34
|
+
const names = result.map((r) => r.index);
|
|
35
|
+
res.json(names);
|
|
36
|
+
} catch (error) {
|
|
37
|
+
res.status(500).json({ error: String(error) });
|
|
38
|
+
}
|
|
39
|
+
});
|
|
40
|
+
router.post("/search", async (req, res) => {
|
|
41
|
+
const body = req.body;
|
|
42
|
+
console.info("Received ES query", { body });
|
|
43
|
+
try {
|
|
44
|
+
const result = await esClient.search(body);
|
|
45
|
+
res.json(result);
|
|
46
|
+
} catch (error) {
|
|
47
|
+
console.error("ES query failed", { error });
|
|
48
|
+
res.status(500).json({ error: String(error) });
|
|
49
|
+
}
|
|
50
|
+
});
|
|
51
|
+
return router;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
exports.createRouter = createRouter;
|
|
55
|
+
//# sourceMappingURL=router.cjs.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"router.cjs.js","sources":["../src/router.ts"],"sourcesContent":["import express from 'express';\nimport Router from 'express-promise-router';\nimport { Client } from '@elastic/elasticsearch';\n\nexport async function createRouter(options: {config: any}): Promise<express.Router> {\n const router = Router();\n router.use(express.json());\n\n const esNode = options.config.getString(\"elastic-devtool.elasticsearch.node\");\n const esUsername = options.config.getString(\"elastic-devtool.elasticsearch.username\");\n const esPassword = options.config.getString(\"elastic-devtool.elasticsearch.password\");\n \n const esClient = new Client({\n node: esNode,\n auth: {\n username: esUsername,\n password: esPassword,\n },\n tls: {\n rejectUnauthorized: false,\n },\n });\n\n router.get('/health', async (_, res) => {\n res.json({ status: 'ok' });\n });\n\n router.get('/indices', async (_, res) => {\n try {\n const result = await esClient.cat.indices({ format: 'json' });\n const names = result.map(r => r.index);\n res.json(names);\n } catch (error) {\n res.status(500).json({ error: String(error) });\n }\n });\n\n router.post('/search', async (req, res) => {\n const body = req.body;\n console.info('Received ES query', { body });\n try {\n const result = await esClient.search(body);\n res.json(result);\n } catch (error) {\n console.error('ES query failed', { error });\n res.status(500).json({ error: String(error) });\n }\n });\n return router;\n}\n"],"names":["Router","express","Client"],"mappings":";;;;;;;;;;;AAIA,eAAsB,aAAa,OAAA,EAAiD;AAClF,EAAA,MAAM,SAASA,uBAAA,EAAO;AACtB,EAAA,MAAA,CAAO,GAAA,CAAIC,wBAAA,CAAQ,IAAA,EAAM,CAAA;AAEzB,EAAA,MAAM,MAAA,GAAS,OAAA,CAAQ,MAAA,CAAO,SAAA,CAAU,oCAAoC,CAAA;AAC5E,EAAA,MAAM,UAAA,GAAa,OAAA,CAAQ,MAAA,CAAO,SAAA,CAAU,wCAAwC,CAAA;AACpF,EAAA,MAAM,UAAA,GAAa,OAAA,CAAQ,MAAA,CAAO,SAAA,CAAU,wCAAwC,CAAA;AAEpF,EAAA,MAAM,QAAA,GAAW,IAAIC,oBAAA,CAAO;AAAA,IAC1B,IAAA,EAAM,MAAA;AAAA,IACN,IAAA,EAAM;AAAA,MACJ,QAAA,EAAU,UAAA;AAAA,MACV,QAAA,EAAU;AAAA,KACZ;AAAA,IACA,GAAA,EAAK;AAAA,MACH,kBAAA,EAAoB;AAAA;AACtB,GACD,CAAA;AAED,EAAA,MAAA,CAAO,GAAA,CAAI,SAAA,EAAW,OAAO,CAAA,EAAG,GAAA,KAAQ;AACtC,IAAA,GAAA,CAAI,IAAA,CAAK,EAAE,MAAA,EAAQ,IAAA,EAAM,CAAA;AAAA,EAC3B,CAAC,CAAA;AAED,EAAA,MAAA,CAAO,GAAA,CAAI,UAAA,EAAY,OAAO,CAAA,EAAG,GAAA,KAAQ;AACvC,IAAA,IAAI;AACF,MAAA,MAAM,MAAA,GAAS,MAAM,QAAA,CAAS,GAAA,CAAI,QAAQ,EAAE,MAAA,EAAQ,QAAQ,CAAA;AAC5D,MAAA,MAAM,KAAA,GAAQ,MAAA,CAAO,GAAA,CAAI,CAAA,CAAA,KAAK,EAAE,KAAK,CAAA;AACrC,MAAA,GAAA,CAAI,KAAK,KAAK,CAAA;AAAA,IAChB,SAAS,KAAA,EAAO;AACd,MAAA,GAAA,CAAI,MAAA,CAAO,GAAG,CAAA,CAAE,IAAA,CAAK,EAAE,KAAA,EAAO,MAAA,CAAO,KAAK,CAAA,EAAG,CAAA;AAAA,IAC/C;AAAA,EACF,CAAC,CAAA;AAED,EAAA,MAAA,CAAO,IAAA,CAAK,SAAA,EAAW,OAAO,GAAA,EAAK,GAAA,KAAQ;AACzC,IAAA,MAAM,OAAO,GAAA,CAAI,IAAA;AACjB,IAAA,OAAA,CAAQ,IAAA,CAAK,mBAAA,EAAqB,EAAE,IAAA,EAAM,CAAA;AAC1C,IAAA,IAAI;AACF,MAAA,MAAM,MAAA,GAAS,MAAM,QAAA,CAAS,MAAA,CAAO,IAAI,CAAA;AACzC,MAAA,GAAA,CAAI,KAAK,MAAM,CAAA;AAAA,IACjB,SAAS,KAAA,EAAO;AACd,MAAA,OAAA,CAAQ,KAAA,CAAM,iBAAA,EAAmB,EAAE,KAAA,EAAO,CAAA;AAC1C,MAAA,GAAA,CAAI,MAAA,CAAO,GAAG,CAAA,CAAE,IAAA,CAAK,EAAE,KAAA,EAAO,MAAA,CAAO,KAAK,CAAA,EAAG,CAAA;AAAA,IAC/C;AAAA,EACF,CAAC,CAAA;AACD,EAAA,OAAO,MAAA;AACT;;;;"}
|
package/package.json
ADDED
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@saishnarvekar/plugin-elastic-devtool-backend",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"license": "Apache-2.0",
|
|
5
|
+
"main": "dist/index.cjs.js",
|
|
6
|
+
"types": "dist/index.d.ts",
|
|
7
|
+
"publishConfig": {
|
|
8
|
+
"access": "public",
|
|
9
|
+
"main": "dist/index.cjs.js",
|
|
10
|
+
"types": "dist/index.d.ts"
|
|
11
|
+
},
|
|
12
|
+
"backstage": {
|
|
13
|
+
"role": "backend-plugin",
|
|
14
|
+
"pluginId": "elastic-devtool",
|
|
15
|
+
"pluginPackages": [
|
|
16
|
+
"@saishnarvekar/plugin-elastic-devtool",
|
|
17
|
+
"@saishnarvekar/plugin-elastic-devtool-backend"
|
|
18
|
+
],
|
|
19
|
+
"features": {
|
|
20
|
+
".": "@backstage/BackendFeature"
|
|
21
|
+
}
|
|
22
|
+
},
|
|
23
|
+
"scripts": {
|
|
24
|
+
"start": "backstage-cli package start",
|
|
25
|
+
"build": "backstage-cli package build",
|
|
26
|
+
"lint": "backstage-cli package lint",
|
|
27
|
+
"test": "backstage-cli package test",
|
|
28
|
+
"clean": "backstage-cli package clean",
|
|
29
|
+
"prepack": "backstage-cli package prepack",
|
|
30
|
+
"postpack": "backstage-cli package postpack"
|
|
31
|
+
},
|
|
32
|
+
"dependencies": {
|
|
33
|
+
"@backstage/backend-defaults": "^0.13.0",
|
|
34
|
+
"@backstage/backend-plugin-api": "^1.4.4",
|
|
35
|
+
"@backstage/catalog-client": "^1.12.0",
|
|
36
|
+
"@backstage/errors": "^1.2.7",
|
|
37
|
+
"@backstage/plugin-catalog-node": "^1.19.1",
|
|
38
|
+
"@backstage/types": "^1.2.2",
|
|
39
|
+
"@elastic/elasticsearch": "^9.2.0",
|
|
40
|
+
"express": "^4.17.1",
|
|
41
|
+
"express-promise-router": "^4.1.0",
|
|
42
|
+
"zod": "^3.22.4"
|
|
43
|
+
},
|
|
44
|
+
"devDependencies": {
|
|
45
|
+
"@backstage/backend-test-utils": "^1.9.1",
|
|
46
|
+
"@backstage/cli": "^0.34.4",
|
|
47
|
+
"@types/express": "^4.17.6",
|
|
48
|
+
"@types/supertest": "^2.0.12",
|
|
49
|
+
"supertest": "^6.2.4"
|
|
50
|
+
},
|
|
51
|
+
"files": [
|
|
52
|
+
"dist"
|
|
53
|
+
],
|
|
54
|
+
"typesVersions": {
|
|
55
|
+
"*": {
|
|
56
|
+
"package.json": [
|
|
57
|
+
"package.json"
|
|
58
|
+
]
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
}
|