@xen-orchestra/rest-api 0.29.0 → 0.30.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/README.md +108 -1
- package/dist/abstract-classes/base-controller.mjs +18 -3
- package/dist/abstract-classes/listener.mjs +116 -12
- package/dist/acl-privileges/acl-privilege.controller.mjs +172 -0
- package/dist/acl-roles/acl-role.controller.mjs +384 -0
- package/dist/alarms/alarm.controller.mjs +22 -9
- package/dist/alarms/alarm.service.mjs +8 -0
- package/dist/backup-archives/backup-archive.controller.mjs +30 -21
- package/dist/backup-archives/backup-archive.service.mjs +21 -0
- package/dist/backup-jobs/backup-job.controller.mjs +59 -15
- package/dist/backup-jobs/backup-job.service.mjs +7 -0
- package/dist/backup-logs/backup-log.controller.mjs +25 -11
- package/dist/backup-logs/backup-log.service.mjs +19 -0
- package/dist/backup-repositories/backup-repositories.controller.mjs +21 -3
- package/dist/events/event.class.mjs +24 -9
- package/dist/events/event.controller.mjs +3 -0
- package/dist/events/event.service.mjs +2 -1
- package/dist/groups/group.controller.mjs +90 -6
- package/dist/hosts/host.controller.mjs +78 -7
- package/dist/ioc/ioc.mjs +13 -4
- package/dist/messages/message.controller.mjs +29 -8
- package/dist/middlewares/acl.middleware.mjs +202 -0
- package/dist/middlewares/authentication.middleware.mjs +15 -6
- package/dist/middlewares/tsoa-to-xo-error.middleware.mjs +19 -1
- package/dist/networks/network.controller.mjs +60 -9
- package/dist/open-api/oa-examples/acl-privilege.oa-example.mjs +25 -0
- package/dist/open-api/oa-examples/acl-role.oa-example.mjs +22 -0
- package/dist/open-api/oa-examples/backup-archive.oa-example.mjs +6 -6
- package/dist/open-api/oa-examples/common.oa-example.mjs +3 -0
- package/dist/open-api/routes/routes.js +676 -132
- package/dist/pbds/pbd.controller.mjs +17 -3
- package/dist/pcis/pci.controller.mjs +16 -3
- package/dist/pgpus/pgpu.controller.mjs +16 -3
- package/dist/pifs/pif.controller.mjs +44 -8
- package/dist/pools/pool.controller.mjs +154 -9
- package/dist/proxies/proxy.controller.mjs +22 -4
- package/dist/restore-logs/restore-log.controller.mjs +36 -19
- package/dist/schedules/schedule.controller.mjs +33 -3
- package/dist/servers/server.controller.mjs +65 -5
- package/dist/sms/sm.controller.mjs +14 -2
- package/dist/srs/sr.controller.mjs +62 -10
- package/dist/tasks/task.controller.mjs +71 -11
- package/dist/users/user.controller.mjs +115 -16
- package/dist/vbds/vbd.controller.mjs +65 -31
- package/dist/vdi-snapshots/vdi-snapshot.controller.mjs +36 -6
- package/dist/vdis/vdi.controller.mjs +69 -8
- package/dist/vifs/vif.controller.mjs +43 -7
- package/dist/vm-controller/vm-controller.controller.mjs +62 -9
- package/dist/vm-snapshots/vm-snapshot.controller.mjs +70 -8
- package/dist/vm-templates/vm-template.controller.mjs +71 -8
- package/dist/vms/vm.controller.mjs +164 -12
- package/open-api/spec/swagger.json +10907 -3265
- package/package.json +4 -3
|
@@ -11,10 +11,11 @@ import { Body, Delete, Example, Get, Middlewares, Path, Post, Put, Query, Reques
|
|
|
11
11
|
import { inject } from 'inversify';
|
|
12
12
|
import { provide } from 'inversify-binding-decorators';
|
|
13
13
|
import { json } from 'express';
|
|
14
|
+
import { acl } from '../middlewares/acl.middleware.mjs';
|
|
14
15
|
import { AlarmService } from '../alarms/alarm.service.mjs';
|
|
15
16
|
import { escapeUnsafeComplexMatcher } from '../helpers/utils.helper.mjs';
|
|
16
17
|
import { genericAlarmsExample } from '../open-api/oa-examples/alarm.oa-example.mjs';
|
|
17
|
-
import { asynchronousActionResp, badRequestResp, createdResp, internalServerErrorResp, noContentResp, notFoundResp, unauthorizedResp, } from '../open-api/common/response.common.mjs';
|
|
18
|
+
import { asynchronousActionResp, badRequestResp, createdResp, forbiddenOperationResp, internalServerErrorResp, noContentResp, notFoundResp, unauthorizedResp, } from '../open-api/common/response.common.mjs';
|
|
18
19
|
import { BASE_URL } from '../index.mjs';
|
|
19
20
|
import { RestApi } from '../rest-api/rest-api.mjs';
|
|
20
21
|
import { XapiXoController } from '../abstract-classes/xapi-xo-controller.mjs';
|
|
@@ -31,17 +32,26 @@ let VdiController = class VdiController extends XapiXoController {
|
|
|
31
32
|
this.#vdiService = vdiService;
|
|
32
33
|
}
|
|
33
34
|
/**
|
|
35
|
+
* Returns all VDIs that match the following privilege:
|
|
36
|
+
* - resource: vdi, action: read
|
|
37
|
+
*
|
|
34
38
|
* @example fields "*"
|
|
35
39
|
* @example filter "snapshots:length:>2"
|
|
36
40
|
* @example limit 42
|
|
37
41
|
*/
|
|
38
42
|
getVdis(req, fields, ndjson, markdown, filter, limit) {
|
|
39
|
-
return this.sendObjects(Object.values(this.getObjects({ filter
|
|
43
|
+
return this.sendObjects(Object.values(this.getObjects({ filter })), req, {
|
|
44
|
+
limit,
|
|
45
|
+
privilege: { action: 'read', resource: 'vdi' },
|
|
46
|
+
});
|
|
40
47
|
}
|
|
41
48
|
/**
|
|
42
49
|
*
|
|
43
50
|
* Export VDI content
|
|
44
51
|
*
|
|
52
|
+
* Required privilege:
|
|
53
|
+
* - resource: vdi, action: export-content
|
|
54
|
+
*
|
|
45
55
|
* @example id "c77f9955-c1d2-4b39-aa1c-73cdb2dacb7e"
|
|
46
56
|
*/
|
|
47
57
|
async exportVdiContent(req, id, format) {
|
|
@@ -55,6 +65,9 @@ let VdiController = class VdiController extends XapiXoController {
|
|
|
55
65
|
*
|
|
56
66
|
* Import VDI content
|
|
57
67
|
*
|
|
68
|
+
* Required privilege:
|
|
69
|
+
* - resource: vdi, action: import-content
|
|
70
|
+
*
|
|
58
71
|
* @example id "c77f9955-c1d2-4b39-aa1c-73cdb2dacb7e"
|
|
59
72
|
*/
|
|
60
73
|
async importVdiContent(req, id, format) {
|
|
@@ -66,12 +79,18 @@ let VdiController = class VdiController extends XapiXoController {
|
|
|
66
79
|
await xapiVdi.$xapi.VDI_importContent(xapiVdi.$ref, req, { format });
|
|
67
80
|
}
|
|
68
81
|
/**
|
|
82
|
+
* Required privilege:
|
|
83
|
+
* - resource: vdi, action: read
|
|
84
|
+
*
|
|
69
85
|
* @example id "c77f9955-c1d2-4b39-aa1c-73cdb2dacb7e"
|
|
70
86
|
*/
|
|
71
87
|
getVdi(id) {
|
|
72
88
|
return this.getObject(id);
|
|
73
89
|
}
|
|
74
90
|
/**
|
|
91
|
+
* Returns all alarms that match the following privilege:
|
|
92
|
+
* - resource: alarm, action: read
|
|
93
|
+
*
|
|
75
94
|
* @example id "c77f9955-c1d2-4b39-aa1c-73cdb2dacb7e"
|
|
76
95
|
* @example fields "id,time"
|
|
77
96
|
* @example filter "time:>1747053793"
|
|
@@ -81,12 +100,15 @@ let VdiController = class VdiController extends XapiXoController {
|
|
|
81
100
|
const vdi = this.getObject(id);
|
|
82
101
|
const alarms = this.#alarmService.getAlarms({
|
|
83
102
|
filter: `${escapeUnsafeComplexMatcher(filter) ?? ''} object:uuid:${vdi.uuid}`,
|
|
103
|
+
});
|
|
104
|
+
return this.sendObjects(Object.values(alarms), req, {
|
|
105
|
+
path: 'alarms',
|
|
84
106
|
limit,
|
|
107
|
+
privilege: { action: 'read', resource: 'alarm' },
|
|
85
108
|
});
|
|
86
|
-
return this.sendObjects(Object.values(alarms), req, 'alarms');
|
|
87
109
|
}
|
|
88
110
|
/**
|
|
89
|
-
* Create an empty VDI
|
|
111
|
+
* Create an empty VDI.
|
|
90
112
|
*
|
|
91
113
|
* @example body { "srId": "c4284e12-37c9-7967-b9e8-83ef229c3e03", "virtual_size": 10737418240, "name_label": "test VDI" }
|
|
92
114
|
*/
|
|
@@ -105,6 +127,9 @@ let VdiController = class VdiController extends XapiXoController {
|
|
|
105
127
|
return { id: vdiUuid };
|
|
106
128
|
}
|
|
107
129
|
/**
|
|
130
|
+
* Required privilege:
|
|
131
|
+
* - resource: vdi, action: delete
|
|
132
|
+
*
|
|
108
133
|
* @example id "c77f9955-c1d2-4b39-aa1c-73cdb2dacb7e"
|
|
109
134
|
*/
|
|
110
135
|
async deleteVdi(id) {
|
|
@@ -112,24 +137,38 @@ let VdiController = class VdiController extends XapiXoController {
|
|
|
112
137
|
await xapiVdi.$xapi.VDI_destroy(xapiVdi.$ref);
|
|
113
138
|
}
|
|
114
139
|
/**
|
|
140
|
+
* Returns all messages that match the following privilege:
|
|
141
|
+
* - resource: message, action: read
|
|
142
|
+
*
|
|
115
143
|
* @example id "c77f9955-c1d2-4b39-aa1c-73cdb2dacb7e"
|
|
116
144
|
* @example fields "name,id,$object"
|
|
117
145
|
* @example filter "name:VM_STARTED"
|
|
118
146
|
* @example limit 42
|
|
119
147
|
*/
|
|
120
148
|
getVdiMessages(req, id, fields, ndjson, markdown, filter, limit) {
|
|
121
|
-
const messages = this.getMessagesForObject(id, { filter
|
|
122
|
-
return this.sendObjects(Object.values(messages), req,
|
|
149
|
+
const messages = this.getMessagesForObject(id, { filter });
|
|
150
|
+
return this.sendObjects(Object.values(messages), req, {
|
|
151
|
+
path: 'messages',
|
|
152
|
+
limit,
|
|
153
|
+
privilege: { action: 'read', resource: 'message' },
|
|
154
|
+
});
|
|
123
155
|
}
|
|
124
156
|
/**
|
|
157
|
+
* Returns all tasks that match the following privilege:
|
|
158
|
+
* - resource: task, action: read
|
|
159
|
+
*
|
|
125
160
|
* @example id "c77f9955-c1d2-4b39-aa1c-73cdb2dacb7e"
|
|
126
161
|
* @example fields "id,status,properties"
|
|
127
162
|
* @example filter "status:failure"
|
|
128
163
|
* @example limit 42
|
|
129
164
|
*/
|
|
130
165
|
async getVdiTasks(req, id, fields, ndjson, markdown, filter, limit) {
|
|
131
|
-
const tasks = await this.getTasksForObject(id, { filter
|
|
132
|
-
return this.sendObjects(Object.values(tasks), req,
|
|
166
|
+
const tasks = await this.getTasksForObject(id, { filter });
|
|
167
|
+
return this.sendObjects(Object.values(tasks), req, {
|
|
168
|
+
path: 'tasks',
|
|
169
|
+
limit,
|
|
170
|
+
privilege: { action: 'read', resource: 'task' },
|
|
171
|
+
});
|
|
133
172
|
}
|
|
134
173
|
/**
|
|
135
174
|
* Migrate a VDI to another SR.
|
|
@@ -153,6 +192,9 @@ let VdiController = class VdiController extends XapiXoController {
|
|
|
153
192
|
});
|
|
154
193
|
}
|
|
155
194
|
/**
|
|
195
|
+
* Required privilege:
|
|
196
|
+
* - resource: vdi, action: update:tags
|
|
197
|
+
*
|
|
156
198
|
* @example id "c77f9955-c1d2-4b39-aa1c-73cdb2dacb7e"
|
|
157
199
|
* @example tag "from-rest-api"
|
|
158
200
|
*/
|
|
@@ -161,6 +203,9 @@ let VdiController = class VdiController extends XapiXoController {
|
|
|
161
203
|
await vdi.$call('add_tags', tag);
|
|
162
204
|
}
|
|
163
205
|
/**
|
|
206
|
+
* Required privilege:
|
|
207
|
+
* - resource: vdi, action: update:tags
|
|
208
|
+
*
|
|
164
209
|
* @example id "c77f9955-c1d2-4b39-aa1c-73cdb2dacb7e"
|
|
165
210
|
* @example tag "from-rest-api"
|
|
166
211
|
*/
|
|
@@ -173,6 +218,7 @@ __decorate([
|
|
|
173
218
|
Example(vdiIds),
|
|
174
219
|
Example(partialVdis),
|
|
175
220
|
Get(''),
|
|
221
|
+
Security('*', ['acl']),
|
|
176
222
|
__param(0, Request()),
|
|
177
223
|
__param(1, Query()),
|
|
178
224
|
__param(2, Query()),
|
|
@@ -182,7 +228,9 @@ __decorate([
|
|
|
182
228
|
], VdiController.prototype, "getVdis", null);
|
|
183
229
|
__decorate([
|
|
184
230
|
Get('{id}.{format}'),
|
|
231
|
+
Middlewares(acl({ resource: 'vdi', action: 'export-content', objectId: 'params.id' })),
|
|
185
232
|
SuccessResponse(200, 'Download started', 'application/octet-stream'),
|
|
233
|
+
Response(forbiddenOperationResp.status, forbiddenOperationResp.description),
|
|
186
234
|
Response(notFoundResp.status, notFoundResp.description),
|
|
187
235
|
Response(422, 'Invalid format'),
|
|
188
236
|
__param(0, Request()),
|
|
@@ -191,7 +239,9 @@ __decorate([
|
|
|
191
239
|
], VdiController.prototype, "exportVdiContent", null);
|
|
192
240
|
__decorate([
|
|
193
241
|
Put('{id}.{format}'),
|
|
242
|
+
Middlewares(acl({ resource: 'vdi', action: 'import-content', objectId: 'params.id' })),
|
|
194
243
|
SuccessResponse(noContentResp.status, noContentResp.description),
|
|
244
|
+
Response(forbiddenOperationResp.status, forbiddenOperationResp.description),
|
|
195
245
|
Response(notFoundResp.status, notFoundResp.description),
|
|
196
246
|
Response(422, 'Invalid format'),
|
|
197
247
|
Response(internalServerErrorResp.status, internalServerErrorResp.description),
|
|
@@ -202,12 +252,15 @@ __decorate([
|
|
|
202
252
|
__decorate([
|
|
203
253
|
Example(vdi),
|
|
204
254
|
Get('{id}'),
|
|
255
|
+
Middlewares(acl({ resource: 'vdi', action: 'read', objectId: 'params.id' })),
|
|
256
|
+
Response(forbiddenOperationResp.status, forbiddenOperationResp.description),
|
|
205
257
|
Response(notFoundResp.status, notFoundResp.description),
|
|
206
258
|
__param(0, Path())
|
|
207
259
|
], VdiController.prototype, "getVdi", null);
|
|
208
260
|
__decorate([
|
|
209
261
|
Example(genericAlarmsExample),
|
|
210
262
|
Get('{id}/alarms'),
|
|
263
|
+
Security('*', ['acl']),
|
|
211
264
|
Tags('alarms'),
|
|
212
265
|
Response(notFoundResp.status, notFoundResp.description),
|
|
213
266
|
__param(0, Request()),
|
|
@@ -229,7 +282,9 @@ __decorate([
|
|
|
229
282
|
], VdiController.prototype, "createVdi", null);
|
|
230
283
|
__decorate([
|
|
231
284
|
Delete('{id}'),
|
|
285
|
+
Middlewares(acl({ resource: 'vdi', action: 'delete', objectId: 'params.id' })),
|
|
232
286
|
SuccessResponse(noContentResp.status, noContentResp.description),
|
|
287
|
+
Response(forbiddenOperationResp.status, forbiddenOperationResp.description),
|
|
233
288
|
Response(notFoundResp.status, notFoundResp.description),
|
|
234
289
|
__param(0, Path())
|
|
235
290
|
], VdiController.prototype, "deleteVdi", null);
|
|
@@ -237,6 +292,7 @@ __decorate([
|
|
|
237
292
|
Example(messageIds),
|
|
238
293
|
Example(partialMessages),
|
|
239
294
|
Get('{id}/messages'),
|
|
295
|
+
Security('*', ['acl']),
|
|
240
296
|
Tags('messages'),
|
|
241
297
|
Response(notFoundResp.status, notFoundResp.description),
|
|
242
298
|
__param(0, Request()),
|
|
@@ -251,6 +307,7 @@ __decorate([
|
|
|
251
307
|
Example(taskIds),
|
|
252
308
|
Example(partialTasks),
|
|
253
309
|
Get('{id}/tasks'),
|
|
310
|
+
Security('*', ['acl']),
|
|
254
311
|
Tags('tasks'),
|
|
255
312
|
Response(notFoundResp.status, notFoundResp.description),
|
|
256
313
|
__param(0, Request()),
|
|
@@ -276,14 +333,18 @@ __decorate([
|
|
|
276
333
|
], VdiController.prototype, "migrateVdi", null);
|
|
277
334
|
__decorate([
|
|
278
335
|
Put('{id}/tags/{tag}'),
|
|
336
|
+
Middlewares(acl({ resource: 'vdi', action: 'update:tags', objectId: 'params.id' })),
|
|
279
337
|
SuccessResponse(noContentResp.status, noContentResp.description),
|
|
338
|
+
Response(forbiddenOperationResp.status, forbiddenOperationResp.description),
|
|
280
339
|
Response(notFoundResp.status, notFoundResp.description),
|
|
281
340
|
__param(0, Path()),
|
|
282
341
|
__param(1, Path())
|
|
283
342
|
], VdiController.prototype, "putVdiTag", null);
|
|
284
343
|
__decorate([
|
|
285
344
|
Delete('{id}/tags/{tag}'),
|
|
345
|
+
Middlewares(acl({ resource: 'vdi', action: 'update:tags', objectId: 'params.id' })),
|
|
286
346
|
SuccessResponse(noContentResp.status, noContentResp.description),
|
|
347
|
+
Response(forbiddenOperationResp.status, forbiddenOperationResp.description),
|
|
287
348
|
Response(notFoundResp.status, notFoundResp.description),
|
|
288
349
|
__param(0, Path()),
|
|
289
350
|
__param(1, Path())
|
|
@@ -10,10 +10,11 @@ var __param = (this && this.__param) || function (paramIndex, decorator) {
|
|
|
10
10
|
import { Body, Delete, Example, Get, Middlewares, Path, Post, Query, Request, Response, Route, Security, SuccessResponse, Tags, } from 'tsoa';
|
|
11
11
|
import { inject } from 'inversify';
|
|
12
12
|
import { json } from 'express';
|
|
13
|
+
import { acl } from '../middlewares/acl.middleware.mjs';
|
|
13
14
|
import { escapeUnsafeComplexMatcher } from '../helpers/utils.helper.mjs';
|
|
14
15
|
import { provide } from 'inversify-binding-decorators';
|
|
15
16
|
import { RestApi } from '../rest-api/rest-api.mjs';
|
|
16
|
-
import { asynchronousActionResp, badRequestResp, createdResp, internalServerErrorResp, invalidParameters as invalidParametersResp, noContentResp, notFoundResp, unauthorizedResp, } from '../open-api/common/response.common.mjs';
|
|
17
|
+
import { asynchronousActionResp, badRequestResp, createdResp, internalServerErrorResp, invalidParameters as invalidParametersResp, noContentResp, forbiddenOperationResp, notFoundResp, unauthorizedResp, } from '../open-api/common/response.common.mjs';
|
|
17
18
|
import { invalidParameters } from 'xo-common/api-errors.js';
|
|
18
19
|
import { XapiXoController } from '../abstract-classes/xapi-xo-controller.mjs';
|
|
19
20
|
import { partialVifs, vif, vifId, vifIds } from '../open-api/oa-examples/vif.oa-example.mjs';
|
|
@@ -28,20 +29,32 @@ let VifController = class VifController extends XapiXoController {
|
|
|
28
29
|
this.#alarmService = alarmService;
|
|
29
30
|
}
|
|
30
31
|
/**
|
|
32
|
+
* Returns all VIFs that match the following privilege:
|
|
33
|
+
* - resource: vif, action: read
|
|
34
|
+
*
|
|
31
35
|
* @example fields "attached,id,device"
|
|
32
36
|
* @example filter "attached?"
|
|
33
37
|
* @example limit 42
|
|
34
38
|
*/
|
|
35
39
|
getVifs(req, fields, ndjson, markdown, filter, limit) {
|
|
36
|
-
return this.sendObjects(Object.values(this.getObjects({ filter
|
|
40
|
+
return this.sendObjects(Object.values(this.getObjects({ filter })), req, {
|
|
41
|
+
limit,
|
|
42
|
+
privilege: { action: 'read', resource: 'vif' },
|
|
43
|
+
});
|
|
37
44
|
}
|
|
38
45
|
/**
|
|
46
|
+
* Required privilege:
|
|
47
|
+
* - resource: vif, action: read
|
|
48
|
+
*
|
|
39
49
|
* @example id "f028c5d4-578a-332c-394e-087aaca32dd3"
|
|
40
50
|
*/
|
|
41
51
|
getVif(id) {
|
|
42
52
|
return this.getObject(id);
|
|
43
53
|
}
|
|
44
54
|
/**
|
|
55
|
+
* Returns all alarms that match the following privilege:
|
|
56
|
+
* - resource: alarm, action: read
|
|
57
|
+
*
|
|
45
58
|
* @example id "f028c5d4-578a-332c-394e-087aaca32dd3"
|
|
46
59
|
* @example fields "id,time"
|
|
47
60
|
* @example filter "time:>1747053793"
|
|
@@ -51,29 +64,46 @@ let VifController = class VifController extends XapiXoController {
|
|
|
51
64
|
const vif = this.getObject(id);
|
|
52
65
|
const alarms = this.#alarmService.getAlarms({
|
|
53
66
|
filter: `${escapeUnsafeComplexMatcher(filter) ?? ''} object:uuid:${vif.uuid}`,
|
|
67
|
+
});
|
|
68
|
+
return this.sendObjects(Object.values(alarms), req, {
|
|
69
|
+
path: 'alarms',
|
|
54
70
|
limit,
|
|
71
|
+
privilege: { action: 'read', resource: 'alarm' },
|
|
55
72
|
});
|
|
56
|
-
return this.sendObjects(Object.values(alarms), req, 'alarms');
|
|
57
73
|
}
|
|
58
74
|
/**
|
|
75
|
+
* Returns all messages that match the following privilege:
|
|
76
|
+
* - resource: message, action: read
|
|
77
|
+
*
|
|
59
78
|
* @example id "f028c5d4-578a-332c-394e-087aaca32dd3"
|
|
60
79
|
* @example fields "name,id,$object"
|
|
61
80
|
* @example filter "name:VM_STARTED"
|
|
62
81
|
* @example limit 42
|
|
63
82
|
*/
|
|
64
83
|
getVifMessages(req, id, fields, ndjson, markdown, filter, limit) {
|
|
65
|
-
const messages = this.getMessagesForObject(id, { filter
|
|
66
|
-
return this.sendObjects(Object.values(messages), req,
|
|
84
|
+
const messages = this.getMessagesForObject(id, { filter });
|
|
85
|
+
return this.sendObjects(Object.values(messages), req, {
|
|
86
|
+
path: 'messages',
|
|
87
|
+
limit,
|
|
88
|
+
privilege: { action: 'read', resource: 'message' },
|
|
89
|
+
});
|
|
67
90
|
}
|
|
68
91
|
/**
|
|
92
|
+
* Returns all tasks that match the following privilege:
|
|
93
|
+
* - resource: task, action: read
|
|
94
|
+
*
|
|
69
95
|
* @example id "f028c5d4-578a-332c-394e-087aaca32dd3"
|
|
70
96
|
* @example fields "id,status,properties"
|
|
71
97
|
* @example filter "status:failure"
|
|
72
98
|
* @example limit 42
|
|
73
99
|
*/
|
|
74
100
|
async getVifTasks(req, id, fields, ndjson, markdown, filter, limit) {
|
|
75
|
-
const tasks = await this.getTasksForObject(id, { filter
|
|
76
|
-
return this.sendObjects(Object.values(tasks), req,
|
|
101
|
+
const tasks = await this.getTasksForObject(id, { filter });
|
|
102
|
+
return this.sendObjects(Object.values(tasks), req, {
|
|
103
|
+
path: 'tasks',
|
|
104
|
+
limit,
|
|
105
|
+
privilege: { action: 'read', resource: 'task' },
|
|
106
|
+
});
|
|
77
107
|
}
|
|
78
108
|
/**
|
|
79
109
|
* @example body {
|
|
@@ -153,6 +183,7 @@ __decorate([
|
|
|
153
183
|
Example(vifIds),
|
|
154
184
|
Example(partialVifs),
|
|
155
185
|
Get(''),
|
|
186
|
+
Security('*', ['acl']),
|
|
156
187
|
__param(0, Request()),
|
|
157
188
|
__param(1, Query()),
|
|
158
189
|
__param(2, Query()),
|
|
@@ -163,12 +194,15 @@ __decorate([
|
|
|
163
194
|
__decorate([
|
|
164
195
|
Example(vif),
|
|
165
196
|
Get('{id}'),
|
|
197
|
+
Middlewares(acl({ resource: 'vif', action: 'read', objectId: 'params.id' })),
|
|
198
|
+
Response(forbiddenOperationResp.status, forbiddenOperationResp.description),
|
|
166
199
|
Response(notFoundResp.status, notFoundResp.description),
|
|
167
200
|
__param(0, Path())
|
|
168
201
|
], VifController.prototype, "getVif", null);
|
|
169
202
|
__decorate([
|
|
170
203
|
Example(genericAlarmsExample),
|
|
171
204
|
Get('{id}/alarms'),
|
|
205
|
+
Security('*', ['acl']),
|
|
172
206
|
Tags('alarms'),
|
|
173
207
|
Response(notFoundResp.status, notFoundResp.description),
|
|
174
208
|
__param(0, Request()),
|
|
@@ -183,6 +217,7 @@ __decorate([
|
|
|
183
217
|
Example(messageIds),
|
|
184
218
|
Example(partialMessages),
|
|
185
219
|
Get('{id}/messages'),
|
|
220
|
+
Security('*', ['acl']),
|
|
186
221
|
Tags('messages'),
|
|
187
222
|
Response(notFoundResp.status, notFoundResp.description),
|
|
188
223
|
__param(0, Request()),
|
|
@@ -197,6 +232,7 @@ __decorate([
|
|
|
197
232
|
Example(taskIds),
|
|
198
233
|
Example(partialTasks),
|
|
199
234
|
Get('{id}/tasks'),
|
|
235
|
+
Security('*', ['acl']),
|
|
200
236
|
Tags('tasks'),
|
|
201
237
|
Response(notFoundResp.status, notFoundResp.description),
|
|
202
238
|
__param(0, Request()),
|
|
@@ -10,11 +10,12 @@ var __param = (this && this.__param) || function (paramIndex, decorator) {
|
|
|
10
10
|
import { inject } from 'inversify';
|
|
11
11
|
import { XapiXoController } from '../abstract-classes/xapi-xo-controller.mjs';
|
|
12
12
|
import { RestApi } from '../rest-api/rest-api.mjs';
|
|
13
|
-
import { Delete, Example, Get, Path, Put, Query, Request, Response, Route, Security, SuccessResponse, Tags } from 'tsoa';
|
|
13
|
+
import { Delete, Example, Get, Path, Put, Query, Request, Response, Route, Security, SuccessResponse, Tags, Middlewares } from 'tsoa';
|
|
14
14
|
import { AlarmService } from '../alarms/alarm.service.mjs';
|
|
15
15
|
import { escapeUnsafeComplexMatcher, limitAndFilterArray } from '../helpers/utils.helper.mjs';
|
|
16
|
+
import { acl } from '../middlewares/acl.middleware.mjs';
|
|
16
17
|
import { genericAlarmsExample } from '../open-api/oa-examples/alarm.oa-example.mjs';
|
|
17
|
-
import { badRequestResp, noContentResp, notFoundResp, unauthorizedResp, } from '../open-api/common/response.common.mjs';
|
|
18
|
+
import { badRequestResp, forbiddenOperationResp, noContentResp, notFoundResp, unauthorizedResp, } from '../open-api/common/response.common.mjs';
|
|
18
19
|
import { provide } from 'inversify-binding-decorators';
|
|
19
20
|
import { partialVmControllers, vmController, vmControllerIds, vmControllerVdis, } from '../open-api/oa-examples/vm-controller.oa-example.mjs';
|
|
20
21
|
import { VmService } from '../vms/vm.service.mjs';
|
|
@@ -29,21 +30,32 @@ let VmControllerController = class VmControllerController extends XapiXoControll
|
|
|
29
30
|
this.#vmService = vmService;
|
|
30
31
|
}
|
|
31
32
|
/**
|
|
33
|
+
* Returns all VM controllers that match the following privilege:
|
|
34
|
+
* - resource: vm-controller, action: read
|
|
32
35
|
*
|
|
33
36
|
* @example fields "type,uuid"
|
|
34
37
|
* @example filter "power_state:Running"
|
|
35
38
|
* @example limit 42
|
|
36
39
|
*/
|
|
37
40
|
getVmControllers(req, fields, ndjson, markdown, filter, limit) {
|
|
38
|
-
return this.sendObjects(Object.values(this.getObjects({ filter
|
|
41
|
+
return this.sendObjects(Object.values(this.getObjects({ filter })), req, {
|
|
42
|
+
limit,
|
|
43
|
+
privilege: { action: 'read', resource: 'vm-controller' },
|
|
44
|
+
});
|
|
39
45
|
}
|
|
40
46
|
/**
|
|
47
|
+
* Required privilege:
|
|
48
|
+
* - resource: vm-controller, action: read
|
|
49
|
+
*
|
|
41
50
|
* @example id "9b4775bd-9493-490a-9afa-f786a44caa4f"
|
|
42
51
|
*/
|
|
43
52
|
getVmController(id) {
|
|
44
53
|
return this.getObject(id);
|
|
45
54
|
}
|
|
46
55
|
/**
|
|
56
|
+
* Returns all alarms that match the following privilege:
|
|
57
|
+
* - resource: alarm, action: read
|
|
58
|
+
*
|
|
47
59
|
* @example id "9b4775bd-9493-490a-9afa-f786a44caa4f"
|
|
48
60
|
* @example fields "id,time"
|
|
49
61
|
* @example filter "time:>1747053793"
|
|
@@ -53,11 +65,17 @@ let VmControllerController = class VmControllerController extends XapiXoControll
|
|
|
53
65
|
const vmController = this.getObject(id);
|
|
54
66
|
const alarms = this.#alarmService.getAlarms({
|
|
55
67
|
filter: `${escapeUnsafeComplexMatcher(filter) ?? ''} object:uuid:${vmController.uuid}`,
|
|
68
|
+
});
|
|
69
|
+
return this.sendObjects(Object.values(alarms), req, {
|
|
70
|
+
path: 'alarms',
|
|
56
71
|
limit,
|
|
72
|
+
privilege: { action: 'read', resource: 'alarm' },
|
|
57
73
|
});
|
|
58
|
-
return this.sendObjects(Object.values(alarms), req, 'alarms');
|
|
59
74
|
}
|
|
60
75
|
/**
|
|
76
|
+
* Returns all VDIs that match the following privilege:
|
|
77
|
+
* - resource: vdi, action: read
|
|
78
|
+
*
|
|
61
79
|
* @example id "9b4775bd-9493-490a-9afa-f786a44caa4f"
|
|
62
80
|
* @example fields "VDI_type,id,name_label"
|
|
63
81
|
* @example filter "VDI_type:user"
|
|
@@ -65,29 +83,50 @@ let VmControllerController = class VmControllerController extends XapiXoControll
|
|
|
65
83
|
*/
|
|
66
84
|
getVmControllerVdis(req, id, fields, ndjson, markdown, filter, limit) {
|
|
67
85
|
const vdis = this.#vmService.getVmVdis(id, 'VM-controller');
|
|
68
|
-
return this.sendObjects(limitAndFilterArray(vdis, { filter
|
|
86
|
+
return this.sendObjects(limitAndFilterArray(vdis, { filter }), req, {
|
|
87
|
+
path: obj => obj.type.toLowerCase() + 's',
|
|
88
|
+
limit,
|
|
89
|
+
privilege: { action: 'read', resource: 'vdi' },
|
|
90
|
+
});
|
|
69
91
|
}
|
|
70
92
|
/**
|
|
93
|
+
* Returns all messages that match the following privilege:
|
|
94
|
+
* - resource: message, action: read
|
|
95
|
+
*
|
|
71
96
|
* @example id "9b4775bd-9493-490a-9afa-f786a44caa4f"
|
|
72
97
|
* @example fields "name,id,$object"
|
|
73
98
|
* @example filter "name:VM_STARTED"
|
|
74
99
|
* @example limit 42
|
|
75
100
|
*/
|
|
76
101
|
getVmControllerMessages(req, id, fields, ndjson, markdown, filter, limit) {
|
|
77
|
-
const messages = this.getMessagesForObject(id, { filter
|
|
78
|
-
return this.sendObjects(Object.values(messages), req,
|
|
102
|
+
const messages = this.getMessagesForObject(id, { filter });
|
|
103
|
+
return this.sendObjects(Object.values(messages), req, {
|
|
104
|
+
path: 'messages',
|
|
105
|
+
limit,
|
|
106
|
+
privilege: { action: 'read', resource: 'message' },
|
|
107
|
+
});
|
|
79
108
|
}
|
|
80
109
|
/**
|
|
110
|
+
* Returns all tasks that match the following privilege:
|
|
111
|
+
* - resource: task, action: read
|
|
112
|
+
*
|
|
81
113
|
* @example id "9b4775bd-9493-490a-9afa-f786a44caa4f"
|
|
82
114
|
* @example fields "id,status,properties"
|
|
83
115
|
* @example filter "status:failure"
|
|
84
116
|
* @example limit 42
|
|
85
117
|
*/
|
|
86
118
|
async getVmControllerTasks(req, id, fields, ndjson, markdown, filter, limit) {
|
|
87
|
-
const tasks = await this.getTasksForObject(id, { filter
|
|
88
|
-
return this.sendObjects(Object.values(tasks), req,
|
|
119
|
+
const tasks = await this.getTasksForObject(id, { filter });
|
|
120
|
+
return this.sendObjects(Object.values(tasks), req, {
|
|
121
|
+
path: 'tasks',
|
|
122
|
+
limit,
|
|
123
|
+
privilege: { action: 'read', resource: 'task' },
|
|
124
|
+
});
|
|
89
125
|
}
|
|
90
126
|
/**
|
|
127
|
+
* Required privilege:
|
|
128
|
+
* - resource: vm-controller, action: update:tags
|
|
129
|
+
*
|
|
91
130
|
* @example id "9b4775bd-9493-490a-9afa-f786a44caa4f"
|
|
92
131
|
* @example tag "from-rest-api"
|
|
93
132
|
*/
|
|
@@ -96,6 +135,9 @@ let VmControllerController = class VmControllerController extends XapiXoControll
|
|
|
96
135
|
await vmController.$call('add_tags', tag);
|
|
97
136
|
}
|
|
98
137
|
/**
|
|
138
|
+
* Required privilege:
|
|
139
|
+
* - resource: vm-controller, action: update:tags
|
|
140
|
+
*
|
|
99
141
|
* @example id "9b4775bd-9493-490a-9afa-f786a44caa4f"
|
|
100
142
|
* @example tag "from-rest-api"
|
|
101
143
|
*/
|
|
@@ -108,6 +150,7 @@ __decorate([
|
|
|
108
150
|
Example(vmControllerIds),
|
|
109
151
|
Example(partialVmControllers),
|
|
110
152
|
Get(''),
|
|
153
|
+
Security('*', ['acl']),
|
|
111
154
|
__param(0, Request()),
|
|
112
155
|
__param(1, Query()),
|
|
113
156
|
__param(2, Query()),
|
|
@@ -118,12 +161,15 @@ __decorate([
|
|
|
118
161
|
__decorate([
|
|
119
162
|
Example(vmController),
|
|
120
163
|
Get('{id}'),
|
|
164
|
+
Middlewares(acl({ resource: 'vm-controller', action: 'read', objectId: 'params.id' })),
|
|
121
165
|
Response(notFoundResp.status, notFoundResp.description),
|
|
166
|
+
Response(forbiddenOperationResp.status, forbiddenOperationResp.description),
|
|
122
167
|
__param(0, Path())
|
|
123
168
|
], VmControllerController.prototype, "getVmController", null);
|
|
124
169
|
__decorate([
|
|
125
170
|
Example(genericAlarmsExample),
|
|
126
171
|
Get('{id}/alarms'),
|
|
172
|
+
Security('*', ['acl']),
|
|
127
173
|
Tags('alarms'),
|
|
128
174
|
Response(notFoundResp.status, notFoundResp.description),
|
|
129
175
|
__param(0, Request()),
|
|
@@ -137,6 +183,7 @@ __decorate([
|
|
|
137
183
|
__decorate([
|
|
138
184
|
Example(vmControllerVdis),
|
|
139
185
|
Get('{id}/vdis'),
|
|
186
|
+
Security('*', ['acl']),
|
|
140
187
|
Tags('vdis'),
|
|
141
188
|
Response(notFoundResp.status, notFoundResp.description),
|
|
142
189
|
__param(0, Request()),
|
|
@@ -151,6 +198,7 @@ __decorate([
|
|
|
151
198
|
Example(messageIds),
|
|
152
199
|
Example(partialMessages),
|
|
153
200
|
Get('{id}/messages'),
|
|
201
|
+
Security('*', ['acl']),
|
|
154
202
|
Tags('messages'),
|
|
155
203
|
Response(notFoundResp.status, notFoundResp.description),
|
|
156
204
|
__param(0, Request()),
|
|
@@ -165,6 +213,7 @@ __decorate([
|
|
|
165
213
|
Example(taskIds),
|
|
166
214
|
Example(partialTasks),
|
|
167
215
|
Get('{id}/tasks'),
|
|
216
|
+
Security('*', ['acl']),
|
|
168
217
|
Tags('tasks'),
|
|
169
218
|
Response(notFoundResp.status, notFoundResp.description),
|
|
170
219
|
__param(0, Request()),
|
|
@@ -177,14 +226,18 @@ __decorate([
|
|
|
177
226
|
], VmControllerController.prototype, "getVmControllerTasks", null);
|
|
178
227
|
__decorate([
|
|
179
228
|
Put('{id}/tags/{tag}'),
|
|
229
|
+
Middlewares(acl({ resource: 'vm-controller', action: 'update:tags', objectId: 'params.id' })),
|
|
180
230
|
SuccessResponse(noContentResp.status, noContentResp.description),
|
|
231
|
+
Response(forbiddenOperationResp.status, forbiddenOperationResp.description),
|
|
181
232
|
Response(notFoundResp.status, notFoundResp.description),
|
|
182
233
|
__param(0, Path()),
|
|
183
234
|
__param(1, Path())
|
|
184
235
|
], VmControllerController.prototype, "putVmControllerTag", null);
|
|
185
236
|
__decorate([
|
|
186
237
|
Delete('{id}/tags/{tag}'),
|
|
238
|
+
Middlewares(acl({ resource: 'vm-controller', action: 'update:tags', objectId: 'params.id' })),
|
|
187
239
|
SuccessResponse(noContentResp.status, noContentResp.description),
|
|
240
|
+
Response(forbiddenOperationResp.status, forbiddenOperationResp.description),
|
|
188
241
|
Response(notFoundResp.status, notFoundResp.description),
|
|
189
242
|
__param(0, Path()),
|
|
190
243
|
__param(1, Path())
|