@xen-orchestra/rest-api 0.31.0 → 0.32.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/dist/acl-privileges/acl-privilege.controller.mjs +7 -2
- package/dist/acl-roles/acl-role.controller.mjs +13 -2
- package/dist/alarms/alarm.controller.mjs +3 -1
- package/dist/backup-archives/backup-archive.controller.mjs +3 -1
- package/dist/backup-jobs/backup-job.controller.mjs +12 -1
- package/dist/backup-logs/backup-log.controller.mjs +3 -1
- package/dist/backup-repositories/backup-repositories.controller.mjs +3 -1
- package/dist/events/event.controller.mjs +4 -1
- package/dist/groups/group.controller.mjs +10 -1
- package/dist/hosts/host.controller.mjs +16 -1
- package/dist/index.mjs +2 -0
- package/dist/mcp/mcp.controller.mjs +59 -0
- package/dist/mcp/mcp.helper.mjs +11 -0
- package/dist/messages/message.controller.mjs +3 -1
- package/dist/middlewares/mcp-gate.middleware.mjs +30 -0
- package/dist/networks/network.controller.mjs +9 -1
- package/dist/open-api/routes/routes.js +33 -1
- package/dist/pbds/pbd.controller.mjs +5 -1
- package/dist/pcis/pci.controller.mjs +3 -1
- package/dist/pgpus/pgpu.controller.mjs +3 -1
- package/dist/pifs/pif.controller.mjs +6 -1
- package/dist/pools/pool.controller.mjs +20 -1
- package/dist/proxies/proxy.controller.mjs +3 -1
- package/dist/restore-logs/restore-log.controller.mjs +5 -1
- package/dist/schedules/schedule.controller.mjs +4 -1
- package/dist/servers/server.controller.mjs +8 -1
- package/dist/sms/sm.controller.mjs +3 -1
- package/dist/srs/sr.controller.mjs +13 -1
- package/dist/tasks/task.controller.mjs +6 -1
- package/dist/users/user.controller.mjs +13 -2
- package/dist/vbds/vbd.controller.mjs +10 -1
- package/dist/vdi-snapshots/vdi-snapshot.controller.mjs +10 -1
- package/dist/vdis/vdi.controller.mjs +13 -1
- package/dist/vifs/vif.controller.mjs +10 -1
- package/dist/vm-controller/vm-controller.controller.mjs +9 -1
- package/dist/vm-snapshots/vm-snapshot.controller.mjs +11 -1
- package/dist/vm-templates/vm-template.controller.mjs +11 -1
- package/dist/vms/vm.controller.mjs +29 -1
- package/dist/xoa/xoa.controller.mjs +4 -1
- package/eslint-rules/index.cjs +7 -0
- package/eslint-rules/require-mcp-expose.cjs +129 -0
- package/open-api/spec/swagger.json +563 -264
- package/package.json +3 -3
- package/tsoa.json +2 -1
|
@@ -7,7 +7,7 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
|
|
|
7
7
|
var __param = (this && this.__param) || function (paramIndex, decorator) {
|
|
8
8
|
return function (target, key) { decorator(target, key, paramIndex); }
|
|
9
9
|
};
|
|
10
|
-
import { Body, Delete, Example, Get, Middlewares, Patch, Path, Post, Query, Request, Response, Route, Security, SuccessResponse, Tags, } from 'tsoa';
|
|
10
|
+
import { Body, Delete, Example, Extension, Get, Middlewares, Patch, Path, Post, Query, Request, Response, Route, Security, SuccessResponse, Tags, } from 'tsoa';
|
|
11
11
|
import { provide } from 'inversify-binding-decorators';
|
|
12
12
|
import { json } from 'express';
|
|
13
13
|
import { acl, actionsFromBody } from '../middlewares/acl.middleware.mjs';
|
|
@@ -98,6 +98,7 @@ let AclPrivilegeController = class AclPrivilegeController extends XoController {
|
|
|
98
98
|
__decorate([
|
|
99
99
|
Example(aclPrivilegeIds),
|
|
100
100
|
Example(partialAclPrivileges),
|
|
101
|
+
Extension('x-mcp-exposure', 'allow'),
|
|
101
102
|
Get(''),
|
|
102
103
|
Security('*', ['acl']),
|
|
103
104
|
__param(0, Request()),
|
|
@@ -108,6 +109,7 @@ __decorate([
|
|
|
108
109
|
], AclPrivilegeController.prototype, "getAclV2Privileges", null);
|
|
109
110
|
__decorate([
|
|
110
111
|
Example(entityId),
|
|
112
|
+
Extension('x-mcp-exposure', 'confirm'),
|
|
111
113
|
Post(''),
|
|
112
114
|
Middlewares([json(), acl({ resource: 'acl-privilege', action: 'create', object: ({ req }) => req.body })]),
|
|
113
115
|
SuccessResponse(createdResp.status, createdResp.description),
|
|
@@ -118,6 +120,7 @@ __decorate([
|
|
|
118
120
|
], AclPrivilegeController.prototype, "createAclV2Privilege", null);
|
|
119
121
|
__decorate([
|
|
120
122
|
Example(aclPrivilege),
|
|
123
|
+
Extension('x-mcp-exposure', 'allow'),
|
|
121
124
|
Get('{id}'),
|
|
122
125
|
Middlewares(acl({
|
|
123
126
|
resource: 'acl-privilege',
|
|
@@ -130,6 +133,7 @@ __decorate([
|
|
|
130
133
|
__param(0, Path())
|
|
131
134
|
], AclPrivilegeController.prototype, "getAclV2Privilege", null);
|
|
132
135
|
__decorate([
|
|
136
|
+
Extension('x-mcp-exposure', 'confirm'),
|
|
133
137
|
Delete('{id}'),
|
|
134
138
|
Middlewares(acl({
|
|
135
139
|
resource: 'acl-privilege',
|
|
@@ -143,6 +147,7 @@ __decorate([
|
|
|
143
147
|
__param(0, Path())
|
|
144
148
|
], AclPrivilegeController.prototype, "deleteAclV2Privilege", null);
|
|
145
149
|
__decorate([
|
|
150
|
+
Extension('x-mcp-exposure', 'confirm'),
|
|
146
151
|
Patch('{id}'),
|
|
147
152
|
Middlewares([
|
|
148
153
|
json(),
|
|
@@ -165,7 +170,7 @@ AclPrivilegeController = __decorate([
|
|
|
165
170
|
Security('*'),
|
|
166
171
|
Response(badRequestResp.status, badRequestResp.description),
|
|
167
172
|
Response(unauthorizedResp.status, unauthorizedResp.description),
|
|
168
|
-
Tags('
|
|
173
|
+
Tags('rbacs'),
|
|
169
174
|
provide(AclPrivilegeController),
|
|
170
175
|
__param(0, inject(RestApi))
|
|
171
176
|
], AclPrivilegeController);
|
|
@@ -7,7 +7,7 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
|
|
|
7
7
|
var __param = (this && this.__param) || function (paramIndex, decorator) {
|
|
8
8
|
return function (target, key) { decorator(target, key, paramIndex); }
|
|
9
9
|
};
|
|
10
|
-
import { Body, Delete, Example, Get, Middlewares, Patch, Path, Post, Put, Query, Request, Response, Route, Security, SuccessResponse, Tags, } from 'tsoa';
|
|
10
|
+
import { Body, Delete, Example, Extension, Get, Middlewares, Patch, Path, Post, Put, Query, Request, Response, Route, Security, SuccessResponse, Tags, } from 'tsoa';
|
|
11
11
|
import { provide } from 'inversify-binding-decorators';
|
|
12
12
|
import { json } from 'express';
|
|
13
13
|
import { acl, actionsFromBody } from '../middlewares/acl.middleware.mjs';
|
|
@@ -201,6 +201,7 @@ let AclRoleController = class AclRoleController extends XoController {
|
|
|
201
201
|
__decorate([
|
|
202
202
|
Example(aclRoleIds),
|
|
203
203
|
Example(partialAclRoles),
|
|
204
|
+
Extension('x-mcp-exposure', 'allow'),
|
|
204
205
|
Get(''),
|
|
205
206
|
Security('*', ['acl']),
|
|
206
207
|
__param(0, Request()),
|
|
@@ -211,6 +212,7 @@ __decorate([
|
|
|
211
212
|
], AclRoleController.prototype, "getAclV2Roles", null);
|
|
212
213
|
__decorate([
|
|
213
214
|
Example(entityId),
|
|
215
|
+
Extension('x-mcp-exposure', 'confirm'),
|
|
214
216
|
Post(''),
|
|
215
217
|
Middlewares([
|
|
216
218
|
json(),
|
|
@@ -227,6 +229,7 @@ __decorate([
|
|
|
227
229
|
], AclRoleController.prototype, "createAclV2Role", null);
|
|
228
230
|
__decorate([
|
|
229
231
|
Example(aclRole),
|
|
232
|
+
Extension('x-mcp-exposure', 'allow'),
|
|
230
233
|
Get('{id}'),
|
|
231
234
|
Middlewares(acl({
|
|
232
235
|
resource: 'acl-role',
|
|
@@ -239,6 +242,7 @@ __decorate([
|
|
|
239
242
|
__param(0, Path())
|
|
240
243
|
], AclRoleController.prototype, "getAclV2Role", null);
|
|
241
244
|
__decorate([
|
|
245
|
+
Extension('x-mcp-exposure', 'confirm'),
|
|
242
246
|
Delete('{id}'),
|
|
243
247
|
Middlewares(acl({
|
|
244
248
|
resource: 'acl-role',
|
|
@@ -252,6 +256,7 @@ __decorate([
|
|
|
252
256
|
__param(0, Path())
|
|
253
257
|
], AclRoleController.prototype, "deleteAclV2Role", null);
|
|
254
258
|
__decorate([
|
|
259
|
+
Extension('x-mcp-exposure', 'confirm'),
|
|
255
260
|
Patch('{id}'),
|
|
256
261
|
Middlewares([
|
|
257
262
|
json(),
|
|
@@ -271,6 +276,7 @@ __decorate([
|
|
|
271
276
|
], AclRoleController.prototype, "updateAclV2Role", null);
|
|
272
277
|
__decorate([
|
|
273
278
|
Example(taskLocation),
|
|
279
|
+
Extension('x-mcp-exposure', 'confirm'),
|
|
274
280
|
Post('{id}/actions/copy'),
|
|
275
281
|
Middlewares([
|
|
276
282
|
json(),
|
|
@@ -304,6 +310,7 @@ __decorate([
|
|
|
304
310
|
__decorate([
|
|
305
311
|
Example(aclPrivilegeIds),
|
|
306
312
|
Example(partialAclPrivileges),
|
|
313
|
+
Extension('x-mcp-exposure', 'allow'),
|
|
307
314
|
Get('{id}/privileges'),
|
|
308
315
|
Security('*', ['acl']),
|
|
309
316
|
Response(notFoundResp.status, notFoundResp.description),
|
|
@@ -315,6 +322,7 @@ __decorate([
|
|
|
315
322
|
__param(5, Query())
|
|
316
323
|
], AclRoleController.prototype, "getAclV2RolePrivileges", null);
|
|
317
324
|
__decorate([
|
|
325
|
+
Extension('x-mcp-exposure', 'confirm'),
|
|
318
326
|
Put('{id}/groups/{groupId}'),
|
|
319
327
|
Middlewares(acl({
|
|
320
328
|
resource: 'acl-role',
|
|
@@ -330,6 +338,7 @@ __decorate([
|
|
|
330
338
|
__param(1, Path())
|
|
331
339
|
], AclRoleController.prototype, "attachAclV2Group", null);
|
|
332
340
|
__decorate([
|
|
341
|
+
Extension('x-mcp-exposure', 'confirm'),
|
|
333
342
|
Delete('{id}/groups/{groupId}'),
|
|
334
343
|
Middlewares(acl({
|
|
335
344
|
resource: 'acl-role',
|
|
@@ -344,6 +353,7 @@ __decorate([
|
|
|
344
353
|
__param(1, Path())
|
|
345
354
|
], AclRoleController.prototype, "detachAclV2Group", null);
|
|
346
355
|
__decorate([
|
|
356
|
+
Extension('x-mcp-exposure', 'confirm'),
|
|
347
357
|
Put('{id}/users/{userId}'),
|
|
348
358
|
Middlewares(acl({
|
|
349
359
|
resource: 'acl-role',
|
|
@@ -359,6 +369,7 @@ __decorate([
|
|
|
359
369
|
__param(1, Path())
|
|
360
370
|
], AclRoleController.prototype, "attachAclV2User", null);
|
|
361
371
|
__decorate([
|
|
372
|
+
Extension('x-mcp-exposure', 'confirm'),
|
|
362
373
|
Delete('{id}/users/{userId}'),
|
|
363
374
|
Middlewares(acl({
|
|
364
375
|
resource: 'acl-role',
|
|
@@ -377,7 +388,7 @@ AclRoleController = __decorate([
|
|
|
377
388
|
Security('*'),
|
|
378
389
|
Response(badRequestResp.status, badRequestResp.description),
|
|
379
390
|
Response(unauthorizedResp.status, unauthorizedResp.description),
|
|
380
|
-
Tags('
|
|
391
|
+
Tags('rbacs'),
|
|
381
392
|
provide(AclRoleController),
|
|
382
393
|
__param(0, inject(RestApi))
|
|
383
394
|
], AclRoleController);
|
|
@@ -7,7 +7,7 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
|
|
|
7
7
|
var __param = (this && this.__param) || function (paramIndex, decorator) {
|
|
8
8
|
return function (target, key) { decorator(target, key, paramIndex); }
|
|
9
9
|
};
|
|
10
|
-
import { Example, Get, Middlewares, Path, Query, Request, Response, Route, Security, Tags } from 'tsoa';
|
|
10
|
+
import { Example, Extension, Get, Middlewares, Path, Query, Request, Response, Route, Security, Tags } from 'tsoa';
|
|
11
11
|
import { inject } from 'inversify';
|
|
12
12
|
import { provide } from 'inversify-binding-decorators';
|
|
13
13
|
import { alarm, alarmIds, partialAlarms } from '../open-api/oa-examples/alarm.oa-example.mjs';
|
|
@@ -61,6 +61,7 @@ let AlarmController = class AlarmController extends XapiXoController {
|
|
|
61
61
|
__decorate([
|
|
62
62
|
Example(alarmIds),
|
|
63
63
|
Example(partialAlarms),
|
|
64
|
+
Extension('x-mcp-exposure', 'allow'),
|
|
64
65
|
Get(''),
|
|
65
66
|
Security('*', ['acl']),
|
|
66
67
|
__param(0, Request()),
|
|
@@ -72,6 +73,7 @@ __decorate([
|
|
|
72
73
|
], AlarmController.prototype, "getAlarms", null);
|
|
73
74
|
__decorate([
|
|
74
75
|
Example(alarm),
|
|
76
|
+
Extension('x-mcp-exposure', 'allow'),
|
|
75
77
|
Get('{id}'),
|
|
76
78
|
Middlewares(acl({
|
|
77
79
|
resource: 'alarm',
|
|
@@ -7,7 +7,7 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
|
|
|
7
7
|
var __param = (this && this.__param) || function (paramIndex, decorator) {
|
|
8
8
|
return function (target, key) { decorator(target, key, paramIndex); }
|
|
9
9
|
};
|
|
10
|
-
import { Example, Get, Middlewares, Path, Query, Request, Response, Route, Security, Tags } from 'tsoa';
|
|
10
|
+
import { Example, Extension, Get, Middlewares, Path, Query, Request, Response, Route, Security, Tags } from 'tsoa';
|
|
11
11
|
import { inject } from 'inversify';
|
|
12
12
|
import { provide } from 'inversify-binding-decorators';
|
|
13
13
|
import { badRequestResp, forbiddenOperationResp, notFoundResp, unauthorizedResp, } from '../open-api/common/response.common.mjs';
|
|
@@ -76,6 +76,7 @@ let BackupArchiveController = class BackupArchiveController extends XoController
|
|
|
76
76
|
__decorate([
|
|
77
77
|
Example(backupArchiveIds),
|
|
78
78
|
Example(partialBackupArchives),
|
|
79
|
+
Extension('x-mcp-exposure', 'allow'),
|
|
79
80
|
Get(''),
|
|
80
81
|
Security('*', ['acl']),
|
|
81
82
|
Response(notFoundResp.status, notFoundResp.description),
|
|
@@ -89,6 +90,7 @@ __decorate([
|
|
|
89
90
|
], BackupArchiveController.prototype, "getBackupArchives", null);
|
|
90
91
|
__decorate([
|
|
91
92
|
Example(backupArchive),
|
|
93
|
+
Extension('x-mcp-exposure', 'allow'),
|
|
92
94
|
Get('{id}'),
|
|
93
95
|
Middlewares(acl({
|
|
94
96
|
resource: 'backup-archive',
|
|
@@ -10,7 +10,7 @@ var __param = (this && this.__param) || function (paramIndex, decorator) {
|
|
|
10
10
|
import { createLogger } from '@xen-orchestra/log';
|
|
11
11
|
import { inject } from 'inversify';
|
|
12
12
|
import { noSuchObject } from 'xo-common/api-errors.js';
|
|
13
|
-
import { Deprecated, Example, Get, Hidden, Middlewares, Path, Query, Request, Response, Route, Security, Tags, } from 'tsoa';
|
|
13
|
+
import { Deprecated, Example, Extension, Get, Hidden, Middlewares, Path, Query, Request, Response, Route, Security, Tags, } from 'tsoa';
|
|
14
14
|
import { provide } from 'inversify-binding-decorators';
|
|
15
15
|
import { acl, autoBindService } from '../middlewares/acl.middleware.mjs';
|
|
16
16
|
import { backupLog, backupLogIds, partialBackupLogs } from '../open-api/oa-examples/backup-log.oa-example.mjs';
|
|
@@ -67,6 +67,7 @@ let BackupJobController = class BackupJobController extends XoController {
|
|
|
67
67
|
__decorate([
|
|
68
68
|
Example(vmBackupJobIds),
|
|
69
69
|
Example(partialVmBackupJobs),
|
|
70
|
+
Extension('x-mcp-exposure', 'allow'),
|
|
70
71
|
Get(''),
|
|
71
72
|
Security('*', ['acl']),
|
|
72
73
|
__param(0, Request()),
|
|
@@ -78,6 +79,7 @@ __decorate([
|
|
|
78
79
|
], BackupJobController.prototype, "getBackupJobs", null);
|
|
79
80
|
__decorate([
|
|
80
81
|
Example(vmBackupJob),
|
|
82
|
+
Extension('x-mcp-exposure', 'allow'),
|
|
81
83
|
Get('{id}'),
|
|
82
84
|
Middlewares(acl({
|
|
83
85
|
resource: 'backup-job',
|
|
@@ -236,6 +238,7 @@ __decorate([
|
|
|
236
238
|
Example(vmBackupJobIds),
|
|
237
239
|
Example(partialVmBackupJobs),
|
|
238
240
|
Deprecated(),
|
|
241
|
+
Extension('x-mcp-exposure', 'allow'),
|
|
239
242
|
Get('jobs/vm'),
|
|
240
243
|
Security('*', ['acl']),
|
|
241
244
|
Tags('backup-jobs'),
|
|
@@ -248,6 +251,7 @@ __decorate([
|
|
|
248
251
|
], DeprecatedBackupController.prototype, "getVmBackupJobs", null);
|
|
249
252
|
__decorate([
|
|
250
253
|
Hidden(),
|
|
254
|
+
Extension('x-mcp-exposure', 'allow'),
|
|
251
255
|
Get('jobs/{id}'),
|
|
252
256
|
Tags('backup-jobs'),
|
|
253
257
|
__param(0, Request()),
|
|
@@ -257,6 +261,7 @@ __decorate([
|
|
|
257
261
|
Example(vmBackupJob),
|
|
258
262
|
Deprecated(),
|
|
259
263
|
Response(notFoundResp.status, notFoundResp.description),
|
|
264
|
+
Extension('x-mcp-exposure', 'allow'),
|
|
260
265
|
Get('jobs/vm/{id}'),
|
|
261
266
|
Tags('backup-jobs'),
|
|
262
267
|
__param(0, Path())
|
|
@@ -265,6 +270,7 @@ __decorate([
|
|
|
265
270
|
Example(metadataBackupJobIds),
|
|
266
271
|
Example(partialMetadataBackupJobs),
|
|
267
272
|
Deprecated(),
|
|
273
|
+
Extension('x-mcp-exposure', 'allow'),
|
|
268
274
|
Get('jobs/metadata'),
|
|
269
275
|
Security('*', ['acl']),
|
|
270
276
|
Tags('backup-jobs'),
|
|
@@ -279,6 +285,7 @@ __decorate([
|
|
|
279
285
|
Example(metadataBackupJob),
|
|
280
286
|
Deprecated(),
|
|
281
287
|
Response(notFoundResp.status, notFoundResp.description),
|
|
288
|
+
Extension('x-mcp-exposure', 'allow'),
|
|
282
289
|
Get('jobs/metadata/{id}'),
|
|
283
290
|
Tags('backup-jobs'),
|
|
284
291
|
__param(0, Path())
|
|
@@ -287,6 +294,7 @@ __decorate([
|
|
|
287
294
|
Example(mirrorBackupJobIds),
|
|
288
295
|
Example(partialMirrorBackupJobs),
|
|
289
296
|
Deprecated(),
|
|
297
|
+
Extension('x-mcp-exposure', 'allow'),
|
|
290
298
|
Get('jobs/mirror'),
|
|
291
299
|
Security('*', ['acl']),
|
|
292
300
|
Tags('backup-jobs'),
|
|
@@ -301,6 +309,7 @@ __decorate([
|
|
|
301
309
|
Example(mirrorBackupJob),
|
|
302
310
|
Deprecated(),
|
|
303
311
|
Response(notFoundResp.status, notFoundResp.description),
|
|
312
|
+
Extension('x-mcp-exposure', 'allow'),
|
|
304
313
|
Get('jobs/mirror/{id}'),
|
|
305
314
|
Tags('backup-jobs'),
|
|
306
315
|
__param(0, Path())
|
|
@@ -309,6 +318,7 @@ __decorate([
|
|
|
309
318
|
Example(backupLogIds),
|
|
310
319
|
Example(partialBackupLogs),
|
|
311
320
|
Deprecated(),
|
|
321
|
+
Extension('x-mcp-exposure', 'allow'),
|
|
312
322
|
Get('logs'),
|
|
313
323
|
Security('*', ['acl']),
|
|
314
324
|
Tags('backup-logs'),
|
|
@@ -322,6 +332,7 @@ __decorate([
|
|
|
322
332
|
__decorate([
|
|
323
333
|
Example(backupLog),
|
|
324
334
|
Deprecated(),
|
|
335
|
+
Extension('x-mcp-exposure', 'allow'),
|
|
325
336
|
Get('logs/{id}'),
|
|
326
337
|
Tags('backup-logs'),
|
|
327
338
|
__param(0, Path())
|
|
@@ -7,7 +7,7 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
|
|
|
7
7
|
var __param = (this && this.__param) || function (paramIndex, decorator) {
|
|
8
8
|
return function (target, key) { decorator(target, key, paramIndex); }
|
|
9
9
|
};
|
|
10
|
-
import { Example, Get, Middlewares, Path, Query, Request, Response, Route, Security, Tags } from 'tsoa';
|
|
10
|
+
import { Example, Extension, Get, Middlewares, Path, Query, Request, Response, Route, Security, Tags } from 'tsoa';
|
|
11
11
|
import { inject } from 'inversify';
|
|
12
12
|
import { provide } from 'inversify-binding-decorators';
|
|
13
13
|
import { backupLog, backupLogIds, partialBackupLogs } from '../open-api/oa-examples/backup-log.oa-example.mjs';
|
|
@@ -56,6 +56,7 @@ let BackupLogController = class BackupLogController extends XoController {
|
|
|
56
56
|
__decorate([
|
|
57
57
|
Example(backupLogIds),
|
|
58
58
|
Example(partialBackupLogs),
|
|
59
|
+
Extension('x-mcp-exposure', 'allow'),
|
|
59
60
|
Get(''),
|
|
60
61
|
Security('*', ['acl']),
|
|
61
62
|
__param(0, Request()),
|
|
@@ -67,6 +68,7 @@ __decorate([
|
|
|
67
68
|
], BackupLogController.prototype, "getBackupLogs", null);
|
|
68
69
|
__decorate([
|
|
69
70
|
Example(backupLog),
|
|
71
|
+
Extension('x-mcp-exposure', 'allow'),
|
|
70
72
|
Get('{id}'),
|
|
71
73
|
Middlewares(acl({
|
|
72
74
|
resource: 'backup-log',
|
|
@@ -7,7 +7,7 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
|
|
|
7
7
|
var __param = (this && this.__param) || function (paramIndex, decorator) {
|
|
8
8
|
return function (target, key) { decorator(target, key, paramIndex); }
|
|
9
9
|
};
|
|
10
|
-
import { Example, Get, Middlewares, Path, Query, Request, Response, Route, Security, Tags } from 'tsoa';
|
|
10
|
+
import { Example, Extension, Get, Middlewares, Path, Query, Request, Response, Route, Security, Tags } from 'tsoa';
|
|
11
11
|
import { inject } from 'inversify';
|
|
12
12
|
import { provide } from 'inversify-binding-decorators';
|
|
13
13
|
import { acl } from '../middlewares/acl.middleware.mjs';
|
|
@@ -53,6 +53,7 @@ let BackupRepositoryController = class BackupRepositoryController extends XoCont
|
|
|
53
53
|
__decorate([
|
|
54
54
|
Example(backupRepositoryIds),
|
|
55
55
|
Example(partialBackupRepositories),
|
|
56
|
+
Extension('x-mcp-exposure', 'allow'),
|
|
56
57
|
Get(''),
|
|
57
58
|
Security('*', ['acl']),
|
|
58
59
|
__param(0, Request()),
|
|
@@ -64,6 +65,7 @@ __decorate([
|
|
|
64
65
|
], BackupRepositoryController.prototype, "getRepositories", null);
|
|
65
66
|
__decorate([
|
|
66
67
|
Example(backupRepository),
|
|
68
|
+
Extension('x-mcp-exposure', 'allow'),
|
|
67
69
|
Get('{id}'),
|
|
68
70
|
Middlewares(acl({
|
|
69
71
|
resource: 'backup-repository',
|
|
@@ -7,7 +7,7 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
|
|
|
7
7
|
var __param = (this && this.__param) || function (paramIndex, decorator) {
|
|
8
8
|
return function (target, key) { decorator(target, key, paramIndex); }
|
|
9
9
|
};
|
|
10
|
-
import { Body, Controller, Example,
|
|
10
|
+
import { Body, Controller, Delete, Example, Extension, Get, Middlewares, Path, Post, Request, Response, Route, Security, SuccessResponse, Tags, } from 'tsoa';
|
|
11
11
|
import { badRequestResp, createdResp, noContentResp, notFoundResp, unauthorizedResp, } from '../open-api/common/response.common.mjs';
|
|
12
12
|
import { provide } from 'inversify-binding-decorators';
|
|
13
13
|
import { inject } from 'inversify';
|
|
@@ -69,6 +69,7 @@ let EventController = class EventController extends Controller {
|
|
|
69
69
|
}
|
|
70
70
|
};
|
|
71
71
|
__decorate([
|
|
72
|
+
Extension('x-mcp-exposure', 'allow'),
|
|
72
73
|
Get(''),
|
|
73
74
|
Security('*', ['acl']),
|
|
74
75
|
SuccessResponse(200, 'OK'),
|
|
@@ -76,6 +77,7 @@ __decorate([
|
|
|
76
77
|
], EventController.prototype, "openSseConnection", null);
|
|
77
78
|
__decorate([
|
|
78
79
|
Example(addSubscription),
|
|
80
|
+
Extension('x-mcp-exposure', 'confirm'),
|
|
79
81
|
Post('{id}/subscriptions'),
|
|
80
82
|
Security('*', ['acl']),
|
|
81
83
|
Middlewares(json()),
|
|
@@ -85,6 +87,7 @@ __decorate([
|
|
|
85
87
|
__param(1, Body())
|
|
86
88
|
], EventController.prototype, "addSubscription", null);
|
|
87
89
|
__decorate([
|
|
90
|
+
Extension('x-mcp-exposure', 'confirm'),
|
|
88
91
|
Delete('{id}/subscriptions/{subscriptionId}'),
|
|
89
92
|
Security('*', ['acl']),
|
|
90
93
|
SuccessResponse(noContentResp.status, noContentResp.description),
|
|
@@ -7,7 +7,7 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
|
|
|
7
7
|
var __param = (this && this.__param) || function (paramIndex, decorator) {
|
|
8
8
|
return function (target, key) { decorator(target, key, paramIndex); }
|
|
9
9
|
};
|
|
10
|
-
import { Body, Delete, Example, Get, Middlewares, Patch, Path, Post, Put, Query, Request, Response, Route, Security, SuccessResponse, Tags, } from 'tsoa';
|
|
10
|
+
import { Body, Delete, Example, Extension, Get, Middlewares, Patch, Path, Post, Put, Query, Request, Response, Route, Security, SuccessResponse, Tags, } from 'tsoa';
|
|
11
11
|
import { inject } from 'inversify';
|
|
12
12
|
import { json } from 'express';
|
|
13
13
|
import { provide } from 'inversify-binding-decorators';
|
|
@@ -167,6 +167,7 @@ let GroupController = class GroupController extends XoController {
|
|
|
167
167
|
__decorate([
|
|
168
168
|
Example(groupIds),
|
|
169
169
|
Example(partialGroups),
|
|
170
|
+
Extension('x-mcp-exposure', 'allow'),
|
|
170
171
|
Get(''),
|
|
171
172
|
Security('*', ['acl']),
|
|
172
173
|
__param(0, Request()),
|
|
@@ -178,6 +179,7 @@ __decorate([
|
|
|
178
179
|
], GroupController.prototype, "getGroups", null);
|
|
179
180
|
__decorate([
|
|
180
181
|
Example(group),
|
|
182
|
+
Extension('x-mcp-exposure', 'allow'),
|
|
181
183
|
Get('{id}'),
|
|
182
184
|
Middlewares(acl({
|
|
183
185
|
resource: 'group',
|
|
@@ -190,6 +192,7 @@ __decorate([
|
|
|
190
192
|
__param(0, Path())
|
|
191
193
|
], GroupController.prototype, "getGroup", null);
|
|
192
194
|
__decorate([
|
|
195
|
+
Extension('x-mcp-exposure', 'confirm'),
|
|
193
196
|
Patch('{id}'),
|
|
194
197
|
Middlewares([
|
|
195
198
|
json(),
|
|
@@ -209,6 +212,7 @@ __decorate([
|
|
|
209
212
|
], GroupController.prototype, "updateGroup", null);
|
|
210
213
|
__decorate([
|
|
211
214
|
Example(groupId),
|
|
215
|
+
Extension('x-mcp-exposure', 'confirm'),
|
|
212
216
|
Post(''),
|
|
213
217
|
Middlewares([json(), acl({ resource: 'group', action: 'create', object: ({ req }) => req.body })]),
|
|
214
218
|
SuccessResponse(createdResp.status, createdResp.description),
|
|
@@ -218,6 +222,7 @@ __decorate([
|
|
|
218
222
|
__param(0, Body())
|
|
219
223
|
], GroupController.prototype, "createGroup", null);
|
|
220
224
|
__decorate([
|
|
225
|
+
Extension('x-mcp-exposure', 'confirm'),
|
|
221
226
|
Delete('{id}'),
|
|
222
227
|
Middlewares(acl({
|
|
223
228
|
resource: 'group',
|
|
@@ -231,6 +236,7 @@ __decorate([
|
|
|
231
236
|
__param(0, Path())
|
|
232
237
|
], GroupController.prototype, "deleteGroup", null);
|
|
233
238
|
__decorate([
|
|
239
|
+
Extension('x-mcp-exposure', 'confirm'),
|
|
234
240
|
Delete('{id}/users/{userId}'),
|
|
235
241
|
Middlewares(acl({
|
|
236
242
|
resource: 'group',
|
|
@@ -245,6 +251,7 @@ __decorate([
|
|
|
245
251
|
__param(1, Path())
|
|
246
252
|
], GroupController.prototype, "removeUserFromGroup", null);
|
|
247
253
|
__decorate([
|
|
254
|
+
Extension('x-mcp-exposure', 'confirm'),
|
|
248
255
|
Put('{id}/users/{userId}'),
|
|
249
256
|
Middlewares(acl({
|
|
250
257
|
resource: 'group',
|
|
@@ -261,6 +268,7 @@ __decorate([
|
|
|
261
268
|
__decorate([
|
|
262
269
|
Example(userIds),
|
|
263
270
|
Example(partialUsers),
|
|
271
|
+
Extension('x-mcp-exposure', 'allow'),
|
|
264
272
|
Get('{id}/users'),
|
|
265
273
|
Security('*', ['acl']),
|
|
266
274
|
Tags('users'),
|
|
@@ -276,6 +284,7 @@ __decorate([
|
|
|
276
284
|
__decorate([
|
|
277
285
|
Example(taskIds),
|
|
278
286
|
Example(partialTasks),
|
|
287
|
+
Extension('x-mcp-exposure', 'allow'),
|
|
279
288
|
Get('{id}/tasks'),
|
|
280
289
|
Security('*', ['acl']),
|
|
281
290
|
Tags('tasks'),
|
|
@@ -7,7 +7,7 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
|
|
|
7
7
|
var __param = (this && this.__param) || function (paramIndex, decorator) {
|
|
8
8
|
return function (target, key) { decorator(target, key, paramIndex); }
|
|
9
9
|
};
|
|
10
|
-
import { Body, Delete, Example, Get, Middlewares, Path, Post, Put, Query, Request, Response, Route, Security, SuccessResponse, Tags, } from 'tsoa';
|
|
10
|
+
import { Body, Delete, Example, Extension, Get, Middlewares, Path, Post, Put, Query, Request, Response, Route, Security, SuccessResponse, Tags, } from 'tsoa';
|
|
11
11
|
import { asyncEach } from '@vates/async-each';
|
|
12
12
|
import { defer } from 'golike-defer';
|
|
13
13
|
import { json } from 'express';
|
|
@@ -317,6 +317,7 @@ let HostController = class HostController extends XapiXoController {
|
|
|
317
317
|
__decorate([
|
|
318
318
|
Example(hostIds),
|
|
319
319
|
Example(partialHosts),
|
|
320
|
+
Extension('x-mcp-exposure', 'allow'),
|
|
320
321
|
Get(''),
|
|
321
322
|
Security('*', ['acl']),
|
|
322
323
|
__param(0, Request()),
|
|
@@ -328,6 +329,7 @@ __decorate([
|
|
|
328
329
|
], HostController.prototype, "getHosts", null);
|
|
329
330
|
__decorate([
|
|
330
331
|
Example(host),
|
|
332
|
+
Extension('x-mcp-exposure', 'allow'),
|
|
331
333
|
Get('{id}'),
|
|
332
334
|
Middlewares(acl({ resource: 'host', action: 'read', objectId: 'params.id' })),
|
|
333
335
|
Response(forbiddenOperationResp.status, forbiddenOperationResp.description),
|
|
@@ -336,6 +338,7 @@ __decorate([
|
|
|
336
338
|
], HostController.prototype, "getHost", null);
|
|
337
339
|
__decorate([
|
|
338
340
|
Example(hostStats),
|
|
341
|
+
Extension('x-mcp-exposure', 'deny'),
|
|
339
342
|
Get('{id}/stats'),
|
|
340
343
|
Middlewares(acl({ resource: 'host', action: 'read', objectId: 'params.id' })),
|
|
341
344
|
Response(forbiddenOperationResp.status, forbiddenOperationResp.description),
|
|
@@ -346,6 +349,7 @@ __decorate([
|
|
|
346
349
|
__param(1, Query())
|
|
347
350
|
], HostController.prototype, "getHostStats", null);
|
|
348
351
|
__decorate([
|
|
352
|
+
Extension('x-mcp-exposure', 'deny'),
|
|
349
353
|
Get('{id}/audit.txt'),
|
|
350
354
|
Middlewares(acl({ resource: 'host', action: 'export:logs', objectId: 'params.id' })),
|
|
351
355
|
SuccessResponse(200, 'Download started', 'application/octet-stream'),
|
|
@@ -356,6 +360,7 @@ __decorate([
|
|
|
356
360
|
__param(1, Path())
|
|
357
361
|
], HostController.prototype, "getAuditLog", null);
|
|
358
362
|
__decorate([
|
|
363
|
+
Extension('x-mcp-exposure', 'deny'),
|
|
359
364
|
Get('{id}/logs.tgz'),
|
|
360
365
|
Middlewares(acl({ resource: 'host', action: 'export:logs', objectId: 'params.id' })),
|
|
361
366
|
SuccessResponse(200, 'Download started', 'application/gzip'),
|
|
@@ -367,6 +372,7 @@ __decorate([
|
|
|
367
372
|
], HostController.prototype, "getHostLogs", null);
|
|
368
373
|
__decorate([
|
|
369
374
|
Example(genericAlarmsExample),
|
|
375
|
+
Extension('x-mcp-exposure', 'allow'),
|
|
370
376
|
Get('{id}/alarms'),
|
|
371
377
|
Security('*', ['acl']),
|
|
372
378
|
Tags('alarms'),
|
|
@@ -381,6 +387,7 @@ __decorate([
|
|
|
381
387
|
], HostController.prototype, "getHostAlarms", null);
|
|
382
388
|
__decorate([
|
|
383
389
|
Example(hostSmt),
|
|
390
|
+
Extension('x-mcp-exposure', 'allow'),
|
|
384
391
|
Get('{id}/smt'),
|
|
385
392
|
Middlewares(acl({ resource: 'host', action: 'read', objectId: 'params.id' })),
|
|
386
393
|
Response(forbiddenOperationResp.status, forbiddenOperationResp.description),
|
|
@@ -390,6 +397,7 @@ __decorate([
|
|
|
390
397
|
], HostController.prototype, "gethostSmt", null);
|
|
391
398
|
__decorate([
|
|
392
399
|
Example(hostMissingPatches),
|
|
400
|
+
Extension('x-mcp-exposure', 'allow'),
|
|
393
401
|
Get('{id}/missing_patches'),
|
|
394
402
|
Middlewares(acl({ resource: 'host', action: 'read', objectId: 'params.id' })),
|
|
395
403
|
Response(forbiddenOperationResp.status, forbiddenOperationResp.description),
|
|
@@ -400,6 +408,7 @@ __decorate([
|
|
|
400
408
|
__decorate([
|
|
401
409
|
Example(messageIds),
|
|
402
410
|
Example(partialMessages),
|
|
411
|
+
Extension('x-mcp-exposure', 'allow'),
|
|
403
412
|
Get('{id}/messages'),
|
|
404
413
|
Security('*', ['acl']),
|
|
405
414
|
Tags('messages'),
|
|
@@ -415,6 +424,7 @@ __decorate([
|
|
|
415
424
|
__decorate([
|
|
416
425
|
Example(taskIds),
|
|
417
426
|
Example(partialTasks),
|
|
427
|
+
Extension('x-mcp-exposure', 'allow'),
|
|
418
428
|
Get('{id}/tasks'),
|
|
419
429
|
Security('*', ['acl']),
|
|
420
430
|
Tags('tasks'),
|
|
@@ -428,6 +438,7 @@ __decorate([
|
|
|
428
438
|
__param(6, Query())
|
|
429
439
|
], HostController.prototype, "getHostTasks", null);
|
|
430
440
|
__decorate([
|
|
441
|
+
Extension('x-mcp-exposure', 'confirm'),
|
|
431
442
|
Put('{id}/tags/{tag}'),
|
|
432
443
|
Middlewares(acl({ resource: 'host', action: 'update:tags', objectId: 'params.id' })),
|
|
433
444
|
SuccessResponse(noContentResp.status, noContentResp.description),
|
|
@@ -437,6 +448,7 @@ __decorate([
|
|
|
437
448
|
__param(1, Path())
|
|
438
449
|
], HostController.prototype, "putHostTag", null);
|
|
439
450
|
__decorate([
|
|
451
|
+
Extension('x-mcp-exposure', 'confirm'),
|
|
440
452
|
Delete('{id}/tags/{tag}'),
|
|
441
453
|
Middlewares(acl({ resource: 'host', action: 'update:tags', objectId: 'params.id' })),
|
|
442
454
|
SuccessResponse(noContentResp.status, noContentResp.description),
|
|
@@ -447,6 +459,7 @@ __decorate([
|
|
|
447
459
|
], HostController.prototype, "deleteHostTag", null);
|
|
448
460
|
__decorate([
|
|
449
461
|
Example(taskLocation),
|
|
462
|
+
Extension('x-mcp-exposure', 'confirm'),
|
|
450
463
|
Post('{id}/actions/management_reconfigure'),
|
|
451
464
|
Middlewares([json(), acl({ resource: 'pif', action: 'update:management', objectId: 'body.pif' })]),
|
|
452
465
|
SuccessResponse(asynchronousActionResp.status, asynchronousActionResp.description),
|
|
@@ -462,6 +475,7 @@ __decorate([
|
|
|
462
475
|
], HostController.prototype, "managementReconfigure", null);
|
|
463
476
|
__decorate([
|
|
464
477
|
Example(taskLocation),
|
|
478
|
+
Extension('x-mcp-exposure', 'confirm'),
|
|
465
479
|
Post('{id}/actions/disable'),
|
|
466
480
|
Middlewares([
|
|
467
481
|
json(),
|
|
@@ -489,6 +503,7 @@ __decorate([
|
|
|
489
503
|
], HostController.prototype, "disable", null);
|
|
490
504
|
__decorate([
|
|
491
505
|
Example(taskLocation),
|
|
506
|
+
Extension('x-mcp-exposure', 'confirm'),
|
|
492
507
|
Post('{id}/actions/enable'),
|
|
493
508
|
Middlewares(acl({ resource: 'host', action: 'enable', objectId: 'params.id' })),
|
|
494
509
|
SuccessResponse(asynchronousActionResp.status, asynchronousActionResp.description),
|
package/dist/index.mjs
CHANGED
|
@@ -6,6 +6,7 @@ import { RegisterRoutes } from './open-api/routes/routes.js';
|
|
|
6
6
|
import { setupContainer } from './ioc/ioc.mjs';
|
|
7
7
|
import { setupApiContext } from './middlewares/authentication.middleware.mjs';
|
|
8
8
|
import { logMiddleware } from './middlewares/log.middleware.mjs';
|
|
9
|
+
import { mcpGateMiddleware } from './middlewares/mcp-gate.middleware.mjs';
|
|
9
10
|
import { createExternalRouter, sendObjects } from './router/external-router.mjs';
|
|
10
11
|
export { sendObjects };
|
|
11
12
|
// Avoid using "import from" to import a json file as this requires assert/with and will break compatibility with recent node versions
|
|
@@ -40,6 +41,7 @@ export default function setupRestApi(express, xoApp) {
|
|
|
40
41
|
const { mountExternalRoute, externalRouter } = createExternalRouter(swaggerOpenApiSpec);
|
|
41
42
|
express.use(BASE_URL, setupApiContext(xoApp));
|
|
42
43
|
express.use(BASE_URL, logMiddleware);
|
|
44
|
+
express.use(BASE_URL, mcpGateMiddleware);
|
|
43
45
|
RegisterRoutes(express);
|
|
44
46
|
express.use(BASE_URL, externalRouter);
|
|
45
47
|
express.get(`${BASE_URL}/docs/swagger.json`, (_req, res) => {
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
2
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
3
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
4
|
+
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;
|
|
5
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
6
|
+
};
|
|
7
|
+
var __param = (this && this.__param) || function (paramIndex, decorator) {
|
|
8
|
+
return function (target, key) { decorator(target, key, paramIndex); }
|
|
9
|
+
};
|
|
10
|
+
import { Controller, Example, Get, Response, Route, Security, SuccessResponse, Tags } from 'tsoa';
|
|
11
|
+
import { inject } from 'inversify';
|
|
12
|
+
import { provide } from 'inversify-binding-decorators';
|
|
13
|
+
import { ApiError } from '../helpers/error.helper.mjs';
|
|
14
|
+
import { isMcpEnabled, MCP_DISABLED_ERROR } from './mcp.helper.mjs';
|
|
15
|
+
import { RestApi } from '../rest-api/rest-api.mjs';
|
|
16
|
+
const ENABLED_RESPONSE = {
|
|
17
|
+
status: 200,
|
|
18
|
+
description: 'MCP is enabled',
|
|
19
|
+
};
|
|
20
|
+
const DISABLED_RESPONSE = {
|
|
21
|
+
status: 503,
|
|
22
|
+
description: 'MCP is disabled by administrator',
|
|
23
|
+
};
|
|
24
|
+
let McpController = class McpController extends Controller {
|
|
25
|
+
#restApi;
|
|
26
|
+
constructor(restApi) {
|
|
27
|
+
super();
|
|
28
|
+
this.#restApi = restApi;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Returns whether MCP is currently enabled on this XO server.
|
|
32
|
+
*
|
|
33
|
+
* The route is publicly reachable (no authentication required) so the
|
|
34
|
+
* `@xen-orchestra/mcp` binary can check the kill-switch at startup,
|
|
35
|
+
* before any credentials have been configured.
|
|
36
|
+
*/
|
|
37
|
+
getMcpStatus() {
|
|
38
|
+
if (!isMcpEnabled(this.#restApi)) {
|
|
39
|
+
throw new ApiError(DISABLED_RESPONSE.description, DISABLED_RESPONSE.status, {
|
|
40
|
+
data: { error: MCP_DISABLED_ERROR },
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
return { enabled: true };
|
|
44
|
+
}
|
|
45
|
+
};
|
|
46
|
+
__decorate([
|
|
47
|
+
Security('none'),
|
|
48
|
+
Example({ enabled: true }),
|
|
49
|
+
Get('status'),
|
|
50
|
+
SuccessResponse(ENABLED_RESPONSE.status, ENABLED_RESPONSE.description),
|
|
51
|
+
Response(DISABLED_RESPONSE.status, DISABLED_RESPONSE.description)
|
|
52
|
+
], McpController.prototype, "getMcpStatus", null);
|
|
53
|
+
McpController = __decorate([
|
|
54
|
+
Route('mcp'),
|
|
55
|
+
Tags('mcp'),
|
|
56
|
+
provide(McpController),
|
|
57
|
+
__param(0, inject(RestApi))
|
|
58
|
+
], McpController);
|
|
59
|
+
export { McpController };
|