@selentar/analitoly 0.1.1
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 +21 -0
- package/README.md +93 -0
- package/api/dist/dashboards/dash_1775220041958_v1r8io.json +829 -0
- package/api/dist/dashboards/dash_1775222037264_1rrsrd.json +309 -0
- package/api/dist/src/agent/agent.controller.d.ts +26 -0
- package/api/dist/src/agent/agent.controller.js +124 -0
- package/api/dist/src/agent/agent.controller.js.map +1 -0
- package/api/dist/src/agent/agent.module.d.ts +2 -0
- package/api/dist/src/agent/agent.module.js +23 -0
- package/api/dist/src/agent/agent.module.js.map +1 -0
- package/api/dist/src/agent/agent.service.d.ts +39 -0
- package/api/dist/src/agent/agent.service.js +389 -0
- package/api/dist/src/agent/agent.service.js.map +1 -0
- package/api/dist/src/agent/mcp-config.d.ts +9 -0
- package/api/dist/src/agent/mcp-config.js +51 -0
- package/api/dist/src/agent/mcp-config.js.map +1 -0
- package/api/dist/src/app.module.d.ts +2 -0
- package/api/dist/src/app.module.js +52 -0
- package/api/dist/src/app.module.js.map +1 -0
- package/api/dist/src/chart/chart.controller.d.ts +8 -0
- package/api/dist/src/chart/chart.controller.js +38 -0
- package/api/dist/src/chart/chart.controller.js.map +1 -0
- package/api/dist/src/chart/chart.module.d.ts +2 -0
- package/api/dist/src/chart/chart.module.js +24 -0
- package/api/dist/src/chart/chart.module.js.map +1 -0
- package/api/dist/src/chart/chart.service.d.ts +32 -0
- package/api/dist/src/chart/chart.service.js +106 -0
- package/api/dist/src/chart/chart.service.js.map +1 -0
- package/api/dist/src/chat/chat.controller.d.ts +14 -0
- package/api/dist/src/chat/chat.controller.js +73 -0
- package/api/dist/src/chat/chat.controller.js.map +1 -0
- package/api/dist/src/chat/chat.module.d.ts +2 -0
- package/api/dist/src/chat/chat.module.js +22 -0
- package/api/dist/src/chat/chat.module.js.map +1 -0
- package/api/dist/src/chat/chat.service.d.ts +25 -0
- package/api/dist/src/chat/chat.service.js +168 -0
- package/api/dist/src/chat/chat.service.js.map +1 -0
- package/api/dist/src/connection/connection.controller.d.ts +46 -0
- package/api/dist/src/connection/connection.controller.js +189 -0
- package/api/dist/src/connection/connection.controller.js.map +1 -0
- package/api/dist/src/connection/connection.model.d.ts +116 -0
- package/api/dist/src/connection/connection.model.js +23 -0
- package/api/dist/src/connection/connection.model.js.map +1 -0
- package/api/dist/src/connection/connection.module.d.ts +2 -0
- package/api/dist/src/connection/connection.module.js +31 -0
- package/api/dist/src/connection/connection.module.js.map +1 -0
- package/api/dist/src/connection/connection.repository.d.ts +16 -0
- package/api/dist/src/connection/connection.repository.js +195 -0
- package/api/dist/src/connection/connection.repository.js.map +1 -0
- package/api/dist/src/connection/connection.service.d.ts +50 -0
- package/api/dist/src/connection/connection.service.js +343 -0
- package/api/dist/src/connection/connection.service.js.map +1 -0
- package/api/dist/src/context/context.controller.d.ts +13 -0
- package/api/dist/src/context/context.controller.js +86 -0
- package/api/dist/src/context/context.controller.js.map +1 -0
- package/api/dist/src/context/context.module.d.ts +2 -0
- package/api/dist/src/context/context.module.js +39 -0
- package/api/dist/src/context/context.module.js.map +1 -0
- package/api/dist/src/context/context.service.d.ts +32 -0
- package/api/dist/src/context/context.service.js +177 -0
- package/api/dist/src/context/context.service.js.map +1 -0
- package/api/dist/src/dashboard/dashboard.controller.d.ts +21 -0
- package/api/dist/src/dashboard/dashboard.controller.js +109 -0
- package/api/dist/src/dashboard/dashboard.controller.js.map +1 -0
- package/api/dist/src/dashboard/dashboard.model.d.ts +15 -0
- package/api/dist/src/dashboard/dashboard.model.js +3 -0
- package/api/dist/src/dashboard/dashboard.model.js.map +1 -0
- package/api/dist/src/dashboard/dashboard.module.d.ts +2 -0
- package/api/dist/src/dashboard/dashboard.module.js +24 -0
- package/api/dist/src/dashboard/dashboard.module.js.map +1 -0
- package/api/dist/src/dashboard/dashboard.repository.d.ts +9 -0
- package/api/dist/src/dashboard/dashboard.repository.js +72 -0
- package/api/dist/src/dashboard/dashboard.repository.js.map +1 -0
- package/api/dist/src/dashboard/dashboard.service.d.ts +14 -0
- package/api/dist/src/dashboard/dashboard.service.js +87 -0
- package/api/dist/src/dashboard/dashboard.service.js.map +1 -0
- package/api/dist/src/datasource/connectors/connector.interface.d.ts +6 -0
- package/api/dist/src/datasource/connectors/connector.interface.js +3 -0
- package/api/dist/src/datasource/connectors/connector.interface.js.map +1 -0
- package/api/dist/src/datasource/connectors/mongo.connector.d.ts +30 -0
- package/api/dist/src/datasource/connectors/mongo.connector.js +167 -0
- package/api/dist/src/datasource/connectors/mongo.connector.js.map +1 -0
- package/api/dist/src/datasource/connectors/mongo.connector.test.d.ts +1 -0
- package/api/dist/src/datasource/connectors/mongo.connector.test.js +179 -0
- package/api/dist/src/datasource/connectors/mongo.connector.test.js.map +1 -0
- package/api/dist/src/datasource/connectors/postgres.connector.d.ts +50 -0
- package/api/dist/src/datasource/connectors/postgres.connector.js +213 -0
- package/api/dist/src/datasource/connectors/postgres.connector.js.map +1 -0
- package/api/dist/src/datasource/connectors/postgres.connector.test.d.ts +1 -0
- package/api/dist/src/datasource/connectors/postgres.connector.test.js +197 -0
- package/api/dist/src/datasource/connectors/postgres.connector.test.js.map +1 -0
- package/api/dist/src/datasource/datasource.controller.d.ts +16 -0
- package/api/dist/src/datasource/datasource.controller.js +79 -0
- package/api/dist/src/datasource/datasource.controller.js.map +1 -0
- package/api/dist/src/datasource/datasource.model.d.ts +26 -0
- package/api/dist/src/datasource/datasource.model.js +3 -0
- package/api/dist/src/datasource/datasource.model.js.map +1 -0
- package/api/dist/src/datasource/datasource.module.d.ts +2 -0
- package/api/dist/src/datasource/datasource.module.js +31 -0
- package/api/dist/src/datasource/datasource.module.js.map +1 -0
- package/api/dist/src/datasource/datasource.repository.d.ts +11 -0
- package/api/dist/src/datasource/datasource.repository.js +61 -0
- package/api/dist/src/datasource/datasource.repository.js.map +1 -0
- package/api/dist/src/datasource/datasource.service.d.ts +28 -0
- package/api/dist/src/datasource/datasource.service.js +95 -0
- package/api/dist/src/datasource/datasource.service.js.map +1 -0
- package/api/dist/src/example/example.controller.d.ts +10 -0
- package/api/dist/src/example/example.controller.js +43 -0
- package/api/dist/src/example/example.controller.js.map +1 -0
- package/api/dist/src/example/example.model.d.ts +6 -0
- package/api/dist/src/example/example.model.js +3 -0
- package/api/dist/src/example/example.model.js.map +1 -0
- package/api/dist/src/example/example.module.d.ts +2 -0
- package/api/dist/src/example/example.module.js +23 -0
- package/api/dist/src/example/example.module.js.map +1 -0
- package/api/dist/src/example/example.repository.d.ts +6 -0
- package/api/dist/src/example/example.repository.js +30 -0
- package/api/dist/src/example/example.repository.js.map +1 -0
- package/api/dist/src/example/example.service.d.ts +10 -0
- package/api/dist/src/example/example.service.js +31 -0
- package/api/dist/src/example/example.service.js.map +1 -0
- package/api/dist/src/integration/integration.controller.d.ts +15 -0
- package/api/dist/src/integration/integration.controller.js +69 -0
- package/api/dist/src/integration/integration.controller.js.map +1 -0
- package/api/dist/src/integration/integration.model.d.ts +17 -0
- package/api/dist/src/integration/integration.model.js +3 -0
- package/api/dist/src/integration/integration.model.js.map +1 -0
- package/api/dist/src/integration/integration.module.d.ts +2 -0
- package/api/dist/src/integration/integration.module.js +24 -0
- package/api/dist/src/integration/integration.module.js.map +1 -0
- package/api/dist/src/integration/integration.repository.d.ts +6 -0
- package/api/dist/src/integration/integration.repository.js +45 -0
- package/api/dist/src/integration/integration.repository.js.map +1 -0
- package/api/dist/src/integration/integration.service.d.ts +12 -0
- package/api/dist/src/integration/integration.service.js +78 -0
- package/api/dist/src/integration/integration.service.js.map +1 -0
- package/api/dist/src/main.d.ts +1 -0
- package/api/dist/src/main.js +19 -0
- package/api/dist/src/main.js.map +1 -0
- package/api/dist/src/mcp/grafana.mcp.d.ts +1 -0
- package/api/dist/src/mcp/grafana.mcp.js +95 -0
- package/api/dist/src/mcp/grafana.mcp.js.map +1 -0
- package/api/dist/src/mcp/graylog.mcp.d.ts +1 -0
- package/api/dist/src/mcp/graylog.mcp.js +241 -0
- package/api/dist/src/mcp/graylog.mcp.js.map +1 -0
- package/api/dist/src/mcp/mcp-server.d.ts +1 -0
- package/api/dist/src/mcp/mcp-server.js +336 -0
- package/api/dist/src/mcp/mcp-server.js.map +1 -0
- package/api/dist/src/paths.d.ts +8 -0
- package/api/dist/src/paths.js +50 -0
- package/api/dist/src/paths.js.map +1 -0
- package/api/dist/src/paths.test.d.ts +1 -0
- package/api/dist/src/paths.test.js +60 -0
- package/api/dist/src/paths.test.js.map +1 -0
- package/api/dist/src/project/project.controller.d.ts +44 -0
- package/api/dist/src/project/project.controller.js +79 -0
- package/api/dist/src/project/project.controller.js.map +1 -0
- package/api/dist/src/project/project.model.d.ts +19 -0
- package/api/dist/src/project/project.model.js +3 -0
- package/api/dist/src/project/project.model.js.map +1 -0
- package/api/dist/src/project/project.module.d.ts +2 -0
- package/api/dist/src/project/project.module.js +24 -0
- package/api/dist/src/project/project.module.js.map +1 -0
- package/api/dist/src/project/project.repository.d.ts +6 -0
- package/api/dist/src/project/project.repository.js +52 -0
- package/api/dist/src/project/project.repository.js.map +1 -0
- package/api/dist/src/project/project.service.d.ts +17 -0
- package/api/dist/src/project/project.service.js +163 -0
- package/api/dist/src/project/project.service.js.map +1 -0
- package/api/dist/tsconfig.tsbuildinfo +1 -0
- package/api/dist/vitest.config.d.ts +2 -0
- package/api/dist/vitest.config.js +10 -0
- package/api/dist/vitest.config.js.map +1 -0
- package/api/public/dist/Analitoly.png +0 -0
- package/api/public/dist/AnalitolyShort.png +0 -0
- package/api/public/dist/Gitlab.png +0 -0
- package/api/public/dist/Grafana.png +0 -0
- package/api/public/dist/Graylog.png +0 -0
- package/api/public/dist/Mongodb.png +0 -0
- package/api/public/dist/PostgreSQL.png +0 -0
- package/api/public/dist/assets/index-BPB3ckw4.js +222 -0
- package/api/public/dist/assets/index-CSAGa0SG.js +227 -0
- package/api/public/dist/index.html +12 -0
- package/bin/analitoly-mcp.js +18 -0
- package/bin/analitoly.js +38 -0
- package/package.json +54 -0
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
3
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
4
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
5
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
6
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
7
|
+
};
|
|
8
|
+
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
9
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
10
|
+
};
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
exports.ExampleController = void 0;
|
|
13
|
+
const common_1 = require("@nestjs/common");
|
|
14
|
+
const example_service_1 = require("./example.service");
|
|
15
|
+
let ExampleController = class ExampleController {
|
|
16
|
+
constructor(service) {
|
|
17
|
+
this.service = service;
|
|
18
|
+
}
|
|
19
|
+
getHealth() {
|
|
20
|
+
return this.service.getHealth();
|
|
21
|
+
}
|
|
22
|
+
getDatasources() {
|
|
23
|
+
return this.service.getDatasources();
|
|
24
|
+
}
|
|
25
|
+
};
|
|
26
|
+
exports.ExampleController = ExampleController;
|
|
27
|
+
__decorate([
|
|
28
|
+
(0, common_1.Get)('health'),
|
|
29
|
+
__metadata("design:type", Function),
|
|
30
|
+
__metadata("design:paramtypes", []),
|
|
31
|
+
__metadata("design:returntype", Object)
|
|
32
|
+
], ExampleController.prototype, "getHealth", null);
|
|
33
|
+
__decorate([
|
|
34
|
+
(0, common_1.Get)('datasources'),
|
|
35
|
+
__metadata("design:type", Function),
|
|
36
|
+
__metadata("design:paramtypes", []),
|
|
37
|
+
__metadata("design:returntype", Array)
|
|
38
|
+
], ExampleController.prototype, "getDatasources", null);
|
|
39
|
+
exports.ExampleController = ExampleController = __decorate([
|
|
40
|
+
(0, common_1.Controller)('example'),
|
|
41
|
+
__metadata("design:paramtypes", [example_service_1.ExampleService])
|
|
42
|
+
], ExampleController);
|
|
43
|
+
//# sourceMappingURL=example.controller.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"example.controller.js","sourceRoot":"","sources":["../../../src/example/example.controller.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,2CAAiD;AACjD,uDAAmD;AAI5C,IAAM,iBAAiB,GAAvB,MAAM,iBAAiB;IAC5B,YAA6B,OAAuB;QAAvB,YAAO,GAAP,OAAO,CAAgB;IAAG,CAAC;IAGxD,SAAS;QACP,OAAO,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,CAAC;IAClC,CAAC;IAGD,cAAc;QACZ,OAAO,IAAI,CAAC,OAAO,CAAC,cAAc,EAAE,CAAC;IACvC,CAAC;CACF,CAAA;AAZY,8CAAiB;AAI5B;IADC,IAAA,YAAG,EAAC,QAAQ,CAAC;;;;kDAGb;AAGD;IADC,IAAA,YAAG,EAAC,aAAa,CAAC;;;;uDAGlB;4BAXU,iBAAiB;IAD7B,IAAA,mBAAU,EAAC,SAAS,CAAC;qCAEkB,gCAAc;GADzC,iBAAiB,CAY7B"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"example.model.js","sourceRoot":"","sources":["../../../src/example/example.model.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
3
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
4
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
5
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
6
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
7
|
+
};
|
|
8
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
|
+
exports.ExampleModule = void 0;
|
|
10
|
+
const common_1 = require("@nestjs/common");
|
|
11
|
+
const example_controller_1 = require("./example.controller");
|
|
12
|
+
const example_service_1 = require("./example.service");
|
|
13
|
+
const example_repository_1 = require("./example.repository");
|
|
14
|
+
let ExampleModule = class ExampleModule {
|
|
15
|
+
};
|
|
16
|
+
exports.ExampleModule = ExampleModule;
|
|
17
|
+
exports.ExampleModule = ExampleModule = __decorate([
|
|
18
|
+
(0, common_1.Module)({
|
|
19
|
+
controllers: [example_controller_1.ExampleController],
|
|
20
|
+
providers: [example_service_1.ExampleService, example_repository_1.ExampleRepository],
|
|
21
|
+
})
|
|
22
|
+
], ExampleModule);
|
|
23
|
+
//# sourceMappingURL=example.module.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"example.module.js","sourceRoot":"","sources":["../../../src/example/example.module.ts"],"names":[],"mappings":";;;;;;;;;AAAA,2CAAwC;AACxC,6DAAyD;AACzD,uDAAmD;AACnD,6DAAyD;AAMlD,IAAM,aAAa,GAAnB,MAAM,aAAa;CAAG,CAAA;AAAhB,sCAAa;wBAAb,aAAa;IAJzB,IAAA,eAAM,EAAC;QACN,WAAW,EAAE,CAAC,sCAAiB,CAAC;QAChC,SAAS,EAAE,CAAC,gCAAc,EAAE,sCAAiB,CAAC;KAC/C,CAAC;GACW,aAAa,CAAG"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
3
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
4
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
5
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
6
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
7
|
+
};
|
|
8
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
|
+
exports.ExampleRepository = void 0;
|
|
10
|
+
const common_1 = require("@nestjs/common");
|
|
11
|
+
let ExampleRepository = class ExampleRepository {
|
|
12
|
+
constructor() {
|
|
13
|
+
this.datasources = [
|
|
14
|
+
{ id: '1', name: 'Main PostgreSQL', type: 'postgresql', status: 'connected' },
|
|
15
|
+
{ id: '2', name: 'Analytics MongoDB', type: 'mongodb', status: 'disconnected' },
|
|
16
|
+
{ id: '3', name: 'Graylog Logs', type: 'graylog', status: 'connected' },
|
|
17
|
+
];
|
|
18
|
+
}
|
|
19
|
+
findAll() {
|
|
20
|
+
return this.datasources;
|
|
21
|
+
}
|
|
22
|
+
findById(id) {
|
|
23
|
+
return this.datasources.find((d) => d.id === id);
|
|
24
|
+
}
|
|
25
|
+
};
|
|
26
|
+
exports.ExampleRepository = ExampleRepository;
|
|
27
|
+
exports.ExampleRepository = ExampleRepository = __decorate([
|
|
28
|
+
(0, common_1.Injectable)()
|
|
29
|
+
], ExampleRepository);
|
|
30
|
+
//# sourceMappingURL=example.repository.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"example.repository.js","sourceRoot":"","sources":["../../../src/example/example.repository.ts"],"names":[],"mappings":";;;;;;;;;AAAA,2CAA4C;AAIrC,IAAM,iBAAiB,GAAvB,MAAM,iBAAiB;IAAvB;QACY,gBAAW,GAAiB;YAC3C,EAAE,EAAE,EAAE,GAAG,EAAE,IAAI,EAAE,iBAAiB,EAAE,IAAI,EAAE,YAAY,EAAE,MAAM,EAAE,WAAW,EAAE;YAC7E,EAAE,EAAE,EAAE,GAAG,EAAE,IAAI,EAAE,mBAAmB,EAAE,IAAI,EAAE,SAAS,EAAE,MAAM,EAAE,cAAc,EAAE;YAC/E,EAAE,EAAE,EAAE,GAAG,EAAE,IAAI,EAAE,cAAc,EAAE,IAAI,EAAE,SAAS,EAAE,MAAM,EAAE,WAAW,EAAE;SACxE,CAAC;IASJ,CAAC;IAPC,OAAO;QACL,OAAO,IAAI,CAAC,WAAW,CAAC;IAC1B,CAAC;IAED,QAAQ,CAAC,EAAU;QACjB,OAAO,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC;IACnD,CAAC;CACF,CAAA;AAdY,8CAAiB;4BAAjB,iBAAiB;IAD7B,IAAA,mBAAU,GAAE;GACA,iBAAiB,CAc7B"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { ExampleRepository } from './example.repository';
|
|
2
|
+
import { Datasource } from './example.model';
|
|
3
|
+
export declare class ExampleService {
|
|
4
|
+
private readonly repository;
|
|
5
|
+
constructor(repository: ExampleRepository);
|
|
6
|
+
getHealth(): {
|
|
7
|
+
status: string;
|
|
8
|
+
};
|
|
9
|
+
getDatasources(): Datasource[];
|
|
10
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
3
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
4
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
5
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
6
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
7
|
+
};
|
|
8
|
+
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
9
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
10
|
+
};
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
exports.ExampleService = void 0;
|
|
13
|
+
const common_1 = require("@nestjs/common");
|
|
14
|
+
const example_repository_1 = require("./example.repository");
|
|
15
|
+
let ExampleService = class ExampleService {
|
|
16
|
+
constructor(repository) {
|
|
17
|
+
this.repository = repository;
|
|
18
|
+
}
|
|
19
|
+
getHealth() {
|
|
20
|
+
return { status: 'ok' };
|
|
21
|
+
}
|
|
22
|
+
getDatasources() {
|
|
23
|
+
return this.repository.findAll();
|
|
24
|
+
}
|
|
25
|
+
};
|
|
26
|
+
exports.ExampleService = ExampleService;
|
|
27
|
+
exports.ExampleService = ExampleService = __decorate([
|
|
28
|
+
(0, common_1.Injectable)(),
|
|
29
|
+
__metadata("design:paramtypes", [example_repository_1.ExampleRepository])
|
|
30
|
+
], ExampleService);
|
|
31
|
+
//# sourceMappingURL=example.service.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"example.service.js","sourceRoot":"","sources":["../../../src/example/example.service.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,2CAA4C;AAC5C,6DAAyD;AAIlD,IAAM,cAAc,GAApB,MAAM,cAAc;IACzB,YAA6B,UAA6B;QAA7B,eAAU,GAAV,UAAU,CAAmB;IAAG,CAAC;IAE9D,SAAS;QACP,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC;IAC1B,CAAC;IAED,cAAc;QACZ,OAAO,IAAI,CAAC,UAAU,CAAC,OAAO,EAAE,CAAC;IACnC,CAAC;CACF,CAAA;AAVY,wCAAc;yBAAd,cAAc;IAD1B,IAAA,mBAAU,GAAE;qCAE8B,sCAAiB;GAD/C,cAAc,CAU1B"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { IntegrationService } from './integration.service';
|
|
2
|
+
import { IntegrationConfig } from './integration.model';
|
|
3
|
+
export declare class IntegrationController {
|
|
4
|
+
private readonly service;
|
|
5
|
+
constructor(service: IntegrationService);
|
|
6
|
+
save(type: string, body: Omit<IntegrationConfig, 'type'>): {
|
|
7
|
+
success: boolean;
|
|
8
|
+
};
|
|
9
|
+
find(type: string): Omit<import("./integration.model").GraylogConfig, "password"> | Omit<import("./integration.model").GrafanaConfig, "serviceAccountToken"> | {
|
|
10
|
+
configured: boolean;
|
|
11
|
+
};
|
|
12
|
+
test(type: string): Promise<{
|
|
13
|
+
connected: boolean;
|
|
14
|
+
}>;
|
|
15
|
+
}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
3
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
4
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
5
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
6
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
7
|
+
};
|
|
8
|
+
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
9
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
10
|
+
};
|
|
11
|
+
var __param = (this && this.__param) || function (paramIndex, decorator) {
|
|
12
|
+
return function (target, key) { decorator(target, key, paramIndex); }
|
|
13
|
+
};
|
|
14
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
+
exports.IntegrationController = void 0;
|
|
16
|
+
const common_1 = require("@nestjs/common");
|
|
17
|
+
const integration_service_1 = require("./integration.service");
|
|
18
|
+
const VALID_TYPES = ['graylog', 'grafana'];
|
|
19
|
+
function validateType(type) {
|
|
20
|
+
if (!VALID_TYPES.includes(type)) {
|
|
21
|
+
throw new common_1.BadRequestException(`Invalid integration type: ${type}. Must be one of: ${VALID_TYPES.join(', ')}`);
|
|
22
|
+
}
|
|
23
|
+
return type;
|
|
24
|
+
}
|
|
25
|
+
let IntegrationController = class IntegrationController {
|
|
26
|
+
constructor(service) {
|
|
27
|
+
this.service = service;
|
|
28
|
+
}
|
|
29
|
+
save(type, body) {
|
|
30
|
+
const validType = validateType(type);
|
|
31
|
+
this.service.save({ ...body, type: validType });
|
|
32
|
+
return { success: true };
|
|
33
|
+
}
|
|
34
|
+
find(type) {
|
|
35
|
+
return this.service.find(validateType(type)) ?? { configured: false };
|
|
36
|
+
}
|
|
37
|
+
async test(type) {
|
|
38
|
+
const connected = await this.service.testConnection(validateType(type));
|
|
39
|
+
return { connected };
|
|
40
|
+
}
|
|
41
|
+
};
|
|
42
|
+
exports.IntegrationController = IntegrationController;
|
|
43
|
+
__decorate([
|
|
44
|
+
(0, common_1.Post)(':type'),
|
|
45
|
+
__param(0, (0, common_1.Param)('type')),
|
|
46
|
+
__param(1, (0, common_1.Body)()),
|
|
47
|
+
__metadata("design:type", Function),
|
|
48
|
+
__metadata("design:paramtypes", [String, Object]),
|
|
49
|
+
__metadata("design:returntype", void 0)
|
|
50
|
+
], IntegrationController.prototype, "save", null);
|
|
51
|
+
__decorate([
|
|
52
|
+
(0, common_1.Get)(':type'),
|
|
53
|
+
__param(0, (0, common_1.Param)('type')),
|
|
54
|
+
__metadata("design:type", Function),
|
|
55
|
+
__metadata("design:paramtypes", [String]),
|
|
56
|
+
__metadata("design:returntype", void 0)
|
|
57
|
+
], IntegrationController.prototype, "find", null);
|
|
58
|
+
__decorate([
|
|
59
|
+
(0, common_1.Post)(':type/test'),
|
|
60
|
+
__param(0, (0, common_1.Param)('type')),
|
|
61
|
+
__metadata("design:type", Function),
|
|
62
|
+
__metadata("design:paramtypes", [String]),
|
|
63
|
+
__metadata("design:returntype", Promise)
|
|
64
|
+
], IntegrationController.prototype, "test", null);
|
|
65
|
+
exports.IntegrationController = IntegrationController = __decorate([
|
|
66
|
+
(0, common_1.Controller)('integration'),
|
|
67
|
+
__metadata("design:paramtypes", [integration_service_1.IntegrationService])
|
|
68
|
+
], IntegrationController);
|
|
69
|
+
//# sourceMappingURL=integration.controller.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"integration.controller.js","sourceRoot":"","sources":["../../../src/integration/integration.controller.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;AAAA,2CAAyF;AACzF,+DAA2D;AAG3D,MAAM,WAAW,GAAsB,CAAC,SAAS,EAAE,SAAS,CAAC,CAAC;AAE9D,SAAS,YAAY,CAAC,IAAY;IAChC,IAAI,CAAC,WAAW,CAAC,QAAQ,CAAC,IAAuB,CAAC,EAAE,CAAC;QACnD,MAAM,IAAI,4BAAmB,CAAC,6BAA6B,IAAI,qBAAqB,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IAChH,CAAC;IACD,OAAO,IAAuB,CAAC;AACjC,CAAC;AAGM,IAAM,qBAAqB,GAA3B,MAAM,qBAAqB;IAChC,YAA6B,OAA2B;QAA3B,YAAO,GAAP,OAAO,CAAoB;IAAG,CAAC;IAG5D,IAAI,CAAgB,IAAY,EAAU,IAAqC;QAC7E,MAAM,SAAS,GAAG,YAAY,CAAC,IAAI,CAAC,CAAC;QACrC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,GAAG,IAAI,EAAE,IAAI,EAAE,SAAS,EAAuB,CAAC,CAAC;QACrE,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;IAC3B,CAAC;IAGD,IAAI,CAAgB,IAAY;QAC9B,OAAO,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,UAAU,EAAE,KAAK,EAAE,CAAC;IACxE,CAAC;IAGK,AAAN,KAAK,CAAC,IAAI,CAAgB,IAAY;QACpC,MAAM,SAAS,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,cAAc,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC,CAAC;QACxE,OAAO,EAAE,SAAS,EAAE,CAAC;IACvB,CAAC;CACF,CAAA;AApBY,sDAAqB;AAIhC;IADC,IAAA,aAAI,EAAC,OAAO,CAAC;IACR,WAAA,IAAA,cAAK,EAAC,MAAM,CAAC,CAAA;IAAgB,WAAA,IAAA,aAAI,GAAE,CAAA;;;;iDAIxC;AAGD;IADC,IAAA,YAAG,EAAC,OAAO,CAAC;IACP,WAAA,IAAA,cAAK,EAAC,MAAM,CAAC,CAAA;;;;iDAElB;AAGK;IADL,IAAA,aAAI,EAAC,YAAY,CAAC;IACP,WAAA,IAAA,cAAK,EAAC,MAAM,CAAC,CAAA;;;;iDAGxB;gCAnBU,qBAAqB;IADjC,IAAA,mBAAU,EAAC,aAAa,CAAC;qCAEc,wCAAkB;GAD7C,qBAAqB,CAoBjC"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
export type IntegrationType = 'graylog' | 'grafana';
|
|
2
|
+
export interface GraylogConfig {
|
|
3
|
+
type: 'graylog';
|
|
4
|
+
baseUrl: string;
|
|
5
|
+
username: string;
|
|
6
|
+
password: string;
|
|
7
|
+
}
|
|
8
|
+
export interface GrafanaConfig {
|
|
9
|
+
type: 'grafana';
|
|
10
|
+
url: string;
|
|
11
|
+
serviceAccountToken: string;
|
|
12
|
+
}
|
|
13
|
+
export type IntegrationConfig = GraylogConfig | GrafanaConfig;
|
|
14
|
+
export interface IntegrationsFile {
|
|
15
|
+
graylog?: GraylogConfig;
|
|
16
|
+
grafana?: GrafanaConfig;
|
|
17
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"integration.model.js","sourceRoot":"","sources":["../../../src/integration/integration.model.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
3
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
4
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
5
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
6
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
7
|
+
};
|
|
8
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
|
+
exports.IntegrationModule = void 0;
|
|
10
|
+
const common_1 = require("@nestjs/common");
|
|
11
|
+
const integration_controller_1 = require("./integration.controller");
|
|
12
|
+
const integration_service_1 = require("./integration.service");
|
|
13
|
+
const integration_repository_1 = require("./integration.repository");
|
|
14
|
+
let IntegrationModule = class IntegrationModule {
|
|
15
|
+
};
|
|
16
|
+
exports.IntegrationModule = IntegrationModule;
|
|
17
|
+
exports.IntegrationModule = IntegrationModule = __decorate([
|
|
18
|
+
(0, common_1.Module)({
|
|
19
|
+
controllers: [integration_controller_1.IntegrationController],
|
|
20
|
+
providers: [integration_service_1.IntegrationService, integration_repository_1.IntegrationRepository],
|
|
21
|
+
exports: [integration_service_1.IntegrationService],
|
|
22
|
+
})
|
|
23
|
+
], IntegrationModule);
|
|
24
|
+
//# sourceMappingURL=integration.module.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"integration.module.js","sourceRoot":"","sources":["../../../src/integration/integration.module.ts"],"names":[],"mappings":";;;;;;;;;AAAA,2CAAwC;AACxC,qEAAiE;AACjE,+DAA2D;AAC3D,qEAAiE;AAO1D,IAAM,iBAAiB,GAAvB,MAAM,iBAAiB;CAAG,CAAA;AAApB,8CAAiB;4BAAjB,iBAAiB;IAL7B,IAAA,eAAM,EAAC;QACN,WAAW,EAAE,CAAC,8CAAqB,CAAC;QACpC,SAAS,EAAE,CAAC,wCAAkB,EAAE,8CAAqB,CAAC;QACtD,OAAO,EAAE,CAAC,wCAAkB,CAAC;KAC9B,CAAC;GACW,iBAAiB,CAAG"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { IntegrationConfig, IntegrationType, IntegrationsFile } from './integration.model';
|
|
2
|
+
export declare class IntegrationRepository {
|
|
3
|
+
save(config: IntegrationConfig): void;
|
|
4
|
+
find(type: IntegrationType): IntegrationConfig | undefined;
|
|
5
|
+
findAll(): IntegrationsFile;
|
|
6
|
+
}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
3
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
4
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
5
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
6
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
7
|
+
};
|
|
8
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
|
+
exports.IntegrationRepository = void 0;
|
|
10
|
+
const common_1 = require("@nestjs/common");
|
|
11
|
+
const connection_repository_1 = require("../connection/connection.repository");
|
|
12
|
+
const connectionRepo = new connection_repository_1.ConnectionRepository();
|
|
13
|
+
let IntegrationRepository = class IntegrationRepository {
|
|
14
|
+
save(config) {
|
|
15
|
+
const existing = connectionRepo.findActive(config.type);
|
|
16
|
+
if (existing) {
|
|
17
|
+
const { type: _, ...cfg } = config;
|
|
18
|
+
connectionRepo.update(existing.id, { config: cfg });
|
|
19
|
+
}
|
|
20
|
+
else {
|
|
21
|
+
const { type: _, ...cfg } = config;
|
|
22
|
+
connectionRepo.create({ type: config.type, name: config.type, config: cfg });
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
find(type) {
|
|
26
|
+
const conn = connectionRepo.findActive(type);
|
|
27
|
+
if (!conn)
|
|
28
|
+
return undefined;
|
|
29
|
+
return { type, ...conn.config };
|
|
30
|
+
}
|
|
31
|
+
findAll() {
|
|
32
|
+
const result = {};
|
|
33
|
+
for (const type of ['graylog', 'grafana']) {
|
|
34
|
+
const conn = connectionRepo.findActive(type);
|
|
35
|
+
if (conn)
|
|
36
|
+
result[type] = { type, ...conn.config };
|
|
37
|
+
}
|
|
38
|
+
return result;
|
|
39
|
+
}
|
|
40
|
+
};
|
|
41
|
+
exports.IntegrationRepository = IntegrationRepository;
|
|
42
|
+
exports.IntegrationRepository = IntegrationRepository = __decorate([
|
|
43
|
+
(0, common_1.Injectable)()
|
|
44
|
+
], IntegrationRepository);
|
|
45
|
+
//# sourceMappingURL=integration.repository.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"integration.repository.js","sourceRoot":"","sources":["../../../src/integration/integration.repository.ts"],"names":[],"mappings":";;;;;;;;;AAAA,2CAA4C;AAE5C,+EAA2E;AAE3E,MAAM,cAAc,GAAG,IAAI,4CAAoB,EAAE,CAAC;AAG3C,IAAM,qBAAqB,GAA3B,MAAM,qBAAqB;IAChC,IAAI,CAAC,MAAyB;QAC5B,MAAM,QAAQ,GAAG,cAAc,CAAC,UAAU,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;QACxD,IAAI,QAAQ,EAAE,CAAC;YACb,MAAM,EAAE,IAAI,EAAE,CAAC,EAAE,GAAG,GAAG,EAAE,GAAG,MAAM,CAAC;YACnC,cAAc,CAAC,MAAM,CAAC,QAAQ,CAAC,EAAE,EAAE,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC,CAAC;QACtD,CAAC;aAAM,CAAC;YACN,MAAM,EAAE,IAAI,EAAE,CAAC,EAAE,GAAG,GAAG,EAAE,GAAG,MAAM,CAAC;YACnC,cAAc,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,MAAM,CAAC,IAAI,EAAE,IAAI,EAAE,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC,CAAC;QAC/E,CAAC;IACH,CAAC;IAED,IAAI,CAAC,IAAqB;QACxB,MAAM,IAAI,GAAG,cAAc,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC;QAC7C,IAAI,CAAC,IAAI;YAAE,OAAO,SAAS,CAAC;QAC5B,OAAO,EAAE,IAAI,EAAE,GAAG,IAAI,CAAC,MAAM,EAAuB,CAAC;IACvD,CAAC;IAED,OAAO;QACL,MAAM,MAAM,GAAqB,EAAE,CAAC;QACpC,KAAK,MAAM,IAAI,IAAI,CAAC,SAAS,EAAE,SAAS,CAAU,EAAE,CAAC;YACnD,MAAM,IAAI,GAAG,cAAc,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC;YAC7C,IAAI,IAAI;gBAAE,MAAM,CAAC,IAAI,CAAC,GAAG,EAAE,IAAI,EAAE,GAAG,IAAI,CAAC,MAAM,EAAS,CAAC;QAC3D,CAAC;QACD,OAAO,MAAM,CAAC;IAChB,CAAC;CACF,CAAA;AA1BY,sDAAqB;gCAArB,qBAAqB;IADjC,IAAA,mBAAU,GAAE;GACA,qBAAqB,CA0BjC"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { IntegrationRepository } from './integration.repository';
|
|
2
|
+
import { IntegrationConfig, IntegrationType, GraylogConfig, GrafanaConfig } from './integration.model';
|
|
3
|
+
export declare class IntegrationService {
|
|
4
|
+
private readonly repository;
|
|
5
|
+
constructor(repository: IntegrationRepository);
|
|
6
|
+
save(config: IntegrationConfig): void;
|
|
7
|
+
find(type: IntegrationType): Omit<GraylogConfig, 'password'> | Omit<GrafanaConfig, 'serviceAccountToken'> | undefined;
|
|
8
|
+
findRaw(type: IntegrationType): IntegrationConfig | undefined;
|
|
9
|
+
testConnection(type: IntegrationType): Promise<boolean>;
|
|
10
|
+
private testGraylog;
|
|
11
|
+
private testGrafana;
|
|
12
|
+
}
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
3
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
4
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
5
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
6
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
7
|
+
};
|
|
8
|
+
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
9
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
10
|
+
};
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
exports.IntegrationService = void 0;
|
|
13
|
+
const common_1 = require("@nestjs/common");
|
|
14
|
+
const integration_repository_1 = require("./integration.repository");
|
|
15
|
+
let IntegrationService = class IntegrationService {
|
|
16
|
+
constructor(repository) {
|
|
17
|
+
this.repository = repository;
|
|
18
|
+
}
|
|
19
|
+
save(config) {
|
|
20
|
+
this.repository.save(config);
|
|
21
|
+
}
|
|
22
|
+
find(type) {
|
|
23
|
+
const config = this.repository.find(type);
|
|
24
|
+
if (!config)
|
|
25
|
+
return undefined;
|
|
26
|
+
if (config.type === 'graylog') {
|
|
27
|
+
const { password: _, ...rest } = config;
|
|
28
|
+
return rest;
|
|
29
|
+
}
|
|
30
|
+
const { serviceAccountToken: _, ...rest } = config;
|
|
31
|
+
return rest;
|
|
32
|
+
}
|
|
33
|
+
findRaw(type) {
|
|
34
|
+
return this.repository.find(type);
|
|
35
|
+
}
|
|
36
|
+
async testConnection(type) {
|
|
37
|
+
const config = this.repository.find(type);
|
|
38
|
+
if (!config)
|
|
39
|
+
throw new common_1.NotFoundException(`No ${type} integration configured`);
|
|
40
|
+
if (config.type === 'graylog') {
|
|
41
|
+
return this.testGraylog(config);
|
|
42
|
+
}
|
|
43
|
+
return this.testGrafana(config);
|
|
44
|
+
}
|
|
45
|
+
async testGraylog(config) {
|
|
46
|
+
try {
|
|
47
|
+
const credentials = Buffer.from(`${config.username}:${config.password}`).toString('base64');
|
|
48
|
+
const url = config.baseUrl.replace(/\/+$/, '');
|
|
49
|
+
const res = await fetch(`${url}/api/system`, {
|
|
50
|
+
headers: { Authorization: `Basic ${credentials}` },
|
|
51
|
+
signal: AbortSignal.timeout(5000),
|
|
52
|
+
});
|
|
53
|
+
return res.ok;
|
|
54
|
+
}
|
|
55
|
+
catch {
|
|
56
|
+
return false;
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
async testGrafana(config) {
|
|
60
|
+
try {
|
|
61
|
+
const url = config.url.replace(/\/+$/, '');
|
|
62
|
+
const res = await fetch(`${url}/api/health`, {
|
|
63
|
+
headers: { Authorization: `Bearer ${config.serviceAccountToken}` },
|
|
64
|
+
signal: AbortSignal.timeout(5000),
|
|
65
|
+
});
|
|
66
|
+
return res.ok;
|
|
67
|
+
}
|
|
68
|
+
catch {
|
|
69
|
+
return false;
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
};
|
|
73
|
+
exports.IntegrationService = IntegrationService;
|
|
74
|
+
exports.IntegrationService = IntegrationService = __decorate([
|
|
75
|
+
(0, common_1.Injectable)(),
|
|
76
|
+
__metadata("design:paramtypes", [integration_repository_1.IntegrationRepository])
|
|
77
|
+
], IntegrationService);
|
|
78
|
+
//# sourceMappingURL=integration.service.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"integration.service.js","sourceRoot":"","sources":["../../../src/integration/integration.service.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const paths_1 = require("./paths");
|
|
4
|
+
const dotenv_1 = require("dotenv");
|
|
5
|
+
(0, dotenv_1.config)({ path: (0, paths_1.envFilePath)() });
|
|
6
|
+
const core_1 = require("@nestjs/core");
|
|
7
|
+
const app_module_1 = require("./app.module");
|
|
8
|
+
const connection_repository_1 = require("./connection/connection.repository");
|
|
9
|
+
async function bootstrap() {
|
|
10
|
+
connection_repository_1.ConnectionRepository.migrateIfNeeded();
|
|
11
|
+
const app = await core_1.NestFactory.create(app_module_1.AppModule);
|
|
12
|
+
app.setGlobalPrefix('api');
|
|
13
|
+
const port = (0, paths_1.serverPort)();
|
|
14
|
+
await app.listen(port);
|
|
15
|
+
console.log(`Analitoly running at http://localhost:${port}`);
|
|
16
|
+
console.log(`Data directory: ${(0, paths_1.dataDir)()}`);
|
|
17
|
+
}
|
|
18
|
+
bootstrap();
|
|
19
|
+
//# sourceMappingURL=main.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"main.js","sourceRoot":"","sources":["../../src/main.ts"],"names":[],"mappings":";;AAAA,mCAA2D;AAC3D,mCAAgC;AAChC,IAAA,eAAM,EAAC,EAAE,IAAI,EAAE,IAAA,mBAAW,GAAE,EAAE,CAAC,CAAC;AAEhC,uCAA2C;AAC3C,6CAAyC;AACzC,8EAA0E;AAE1E,KAAK,UAAU,SAAS;IACtB,4CAAoB,CAAC,eAAe,EAAE,CAAC;IACvC,MAAM,GAAG,GAAG,MAAM,kBAAW,CAAC,MAAM,CAAC,sBAAS,CAAC,CAAC;IAChD,GAAG,CAAC,eAAe,CAAC,KAAK,CAAC,CAAC;IAC3B,MAAM,IAAI,GAAG,IAAA,kBAAU,GAAE,CAAC;IAC1B,MAAM,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;IACvB,OAAO,CAAC,GAAG,CAAC,yCAAyC,IAAI,EAAE,CAAC,CAAC;IAC7D,OAAO,CAAC,GAAG,CAAC,mBAAmB,IAAA,eAAO,GAAE,EAAE,CAAC,CAAC;AAC9C,CAAC;AACD,SAAS,EAAE,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const mcp_js_1 = require("@modelcontextprotocol/sdk/server/mcp.js");
|
|
4
|
+
const stdio_js_1 = require("@modelcontextprotocol/sdk/server/stdio.js");
|
|
5
|
+
const zod_1 = require("zod");
|
|
6
|
+
const GRAFANA_URL = process.env.GRAFANA_URL?.replace(/\/$/, '');
|
|
7
|
+
const GRAFANA_TOKEN = process.env.GRAFANA_TOKEN;
|
|
8
|
+
if (!GRAFANA_URL || !GRAFANA_TOKEN) {
|
|
9
|
+
console.error('GRAFANA_URL and GRAFANA_TOKEN env vars are required');
|
|
10
|
+
process.exit(1);
|
|
11
|
+
}
|
|
12
|
+
async function grafanaFetch(path, init) {
|
|
13
|
+
const res = await fetch(`${GRAFANA_URL}${path}`, {
|
|
14
|
+
...init,
|
|
15
|
+
headers: {
|
|
16
|
+
Authorization: `Bearer ${GRAFANA_TOKEN}`,
|
|
17
|
+
'Content-Type': 'application/json',
|
|
18
|
+
...init?.headers,
|
|
19
|
+
},
|
|
20
|
+
});
|
|
21
|
+
if (!res.ok) {
|
|
22
|
+
const text = await res.text();
|
|
23
|
+
throw new Error(`Grafana API ${res.status}: ${text}`);
|
|
24
|
+
}
|
|
25
|
+
return res.json();
|
|
26
|
+
}
|
|
27
|
+
const server = new mcp_js_1.McpServer({
|
|
28
|
+
name: 'grafana',
|
|
29
|
+
version: '1.0.0',
|
|
30
|
+
});
|
|
31
|
+
server.tool('search_dashboards', 'Search Grafana dashboards by query string', {
|
|
32
|
+
query: zod_1.z.string().optional().describe('Search query (empty for all dashboards)'),
|
|
33
|
+
limit: zod_1.z.number().default(20).describe('Max results'),
|
|
34
|
+
}, async ({ query, limit }) => {
|
|
35
|
+
const params = new URLSearchParams({ limit: String(limit) });
|
|
36
|
+
if (query)
|
|
37
|
+
params.set('query', query);
|
|
38
|
+
const data = await grafanaFetch(`/api/search?${params}`);
|
|
39
|
+
return {
|
|
40
|
+
content: [{ type: 'text', text: JSON.stringify(data, null, 2) }],
|
|
41
|
+
};
|
|
42
|
+
});
|
|
43
|
+
server.tool('get_dashboard', 'Get full dashboard details by UID', {
|
|
44
|
+
uid: zod_1.z.string().describe('Dashboard UID'),
|
|
45
|
+
}, async ({ uid }) => {
|
|
46
|
+
const data = await grafanaFetch(`/api/dashboards/uid/${uid}`);
|
|
47
|
+
return {
|
|
48
|
+
content: [{ type: 'text', text: JSON.stringify(data, null, 2) }],
|
|
49
|
+
};
|
|
50
|
+
});
|
|
51
|
+
server.tool('query_datasource', 'Execute a query against a Grafana datasource (Prometheus, Loki, etc.)', {
|
|
52
|
+
datasourceUid: zod_1.z.string().describe('Datasource UID'),
|
|
53
|
+
expr: zod_1.z.string().describe('Query expression (PromQL, LogQL, etc.)'),
|
|
54
|
+
from: zod_1.z.string().default('now-1h').describe('Start time (e.g. now-1h, now-24h)'),
|
|
55
|
+
to: zod_1.z.string().default('now').describe('End time (e.g. now)'),
|
|
56
|
+
}, async ({ datasourceUid, expr, from, to }) => {
|
|
57
|
+
const body = {
|
|
58
|
+
queries: [
|
|
59
|
+
{
|
|
60
|
+
refId: 'A',
|
|
61
|
+
datasource: { uid: datasourceUid },
|
|
62
|
+
expr,
|
|
63
|
+
intervalMs: 60000,
|
|
64
|
+
maxDataPoints: 100,
|
|
65
|
+
},
|
|
66
|
+
],
|
|
67
|
+
from,
|
|
68
|
+
to,
|
|
69
|
+
};
|
|
70
|
+
const data = await grafanaFetch('/api/ds/query', {
|
|
71
|
+
method: 'POST',
|
|
72
|
+
body: JSON.stringify(body),
|
|
73
|
+
});
|
|
74
|
+
return {
|
|
75
|
+
content: [{ type: 'text', text: JSON.stringify(data, null, 2) }],
|
|
76
|
+
};
|
|
77
|
+
});
|
|
78
|
+
server.tool('list_alerts', 'List current firing and pending alerts from Grafana Alertmanager', {}, async () => {
|
|
79
|
+
const data = await grafanaFetch('/api/alertmanager/grafana/api/v2/alerts');
|
|
80
|
+
return {
|
|
81
|
+
content: [{ type: 'text', text: JSON.stringify(data, null, 2) }],
|
|
82
|
+
};
|
|
83
|
+
});
|
|
84
|
+
server.tool('list_datasources', 'List all configured Grafana datasources', {}, async () => {
|
|
85
|
+
const data = await grafanaFetch('/api/datasources');
|
|
86
|
+
return {
|
|
87
|
+
content: [{ type: 'text', text: JSON.stringify(data, null, 2) }],
|
|
88
|
+
};
|
|
89
|
+
});
|
|
90
|
+
const transport = new stdio_js_1.StdioServerTransport();
|
|
91
|
+
server.connect(transport).catch((err) => {
|
|
92
|
+
console.error('Grafana MCP server error:', err);
|
|
93
|
+
process.exit(1);
|
|
94
|
+
});
|
|
95
|
+
//# sourceMappingURL=grafana.mcp.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"grafana.mcp.js","sourceRoot":"","sources":["../../../src/mcp/grafana.mcp.ts"],"names":[],"mappings":"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"}
|