@xen-orchestra/rest-api 0.29.0 → 0.30.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.
Files changed (53) hide show
  1. package/README.md +101 -1
  2. package/dist/abstract-classes/base-controller.mjs +20 -3
  3. package/dist/abstract-classes/listener.mjs +116 -12
  4. package/dist/acl-privileges/acl-privilege.controller.mjs +172 -0
  5. package/dist/acl-roles/acl-role.controller.mjs +384 -0
  6. package/dist/alarms/alarm.controller.mjs +22 -9
  7. package/dist/alarms/alarm.service.mjs +8 -0
  8. package/dist/backup-archives/backup-archive.controller.mjs +30 -21
  9. package/dist/backup-archives/backup-archive.service.mjs +21 -0
  10. package/dist/backup-jobs/backup-job.controller.mjs +59 -15
  11. package/dist/backup-jobs/backup-job.service.mjs +7 -0
  12. package/dist/backup-logs/backup-log.controller.mjs +25 -11
  13. package/dist/backup-logs/backup-log.service.mjs +19 -0
  14. package/dist/backup-repositories/backup-repositories.controller.mjs +21 -3
  15. package/dist/events/event.class.mjs +24 -9
  16. package/dist/events/event.controller.mjs +3 -0
  17. package/dist/events/event.service.mjs +2 -1
  18. package/dist/groups/group.controller.mjs +90 -6
  19. package/dist/hosts/host.controller.mjs +78 -7
  20. package/dist/ioc/ioc.mjs +13 -4
  21. package/dist/messages/message.controller.mjs +29 -8
  22. package/dist/middlewares/acl.middleware.mjs +206 -0
  23. package/dist/middlewares/authentication.middleware.mjs +15 -6
  24. package/dist/middlewares/tsoa-to-xo-error.middleware.mjs +19 -1
  25. package/dist/networks/network.controller.mjs +60 -9
  26. package/dist/open-api/oa-examples/acl-privilege.oa-example.mjs +25 -0
  27. package/dist/open-api/oa-examples/acl-role.oa-example.mjs +22 -0
  28. package/dist/open-api/oa-examples/backup-archive.oa-example.mjs +6 -6
  29. package/dist/open-api/oa-examples/common.oa-example.mjs +3 -0
  30. package/dist/open-api/routes/routes.js +676 -132
  31. package/dist/pbds/pbd.controller.mjs +17 -3
  32. package/dist/pcis/pci.controller.mjs +16 -3
  33. package/dist/pgpus/pgpu.controller.mjs +16 -3
  34. package/dist/pifs/pif.controller.mjs +44 -8
  35. package/dist/pools/pool.controller.mjs +154 -9
  36. package/dist/proxies/proxy.controller.mjs +22 -4
  37. package/dist/restore-logs/restore-log.controller.mjs +36 -19
  38. package/dist/schedules/schedule.controller.mjs +33 -3
  39. package/dist/servers/server.controller.mjs +65 -5
  40. package/dist/sms/sm.controller.mjs +14 -2
  41. package/dist/srs/sr.controller.mjs +62 -10
  42. package/dist/tasks/task.controller.mjs +75 -11
  43. package/dist/users/user.controller.mjs +115 -16
  44. package/dist/vbds/vbd.controller.mjs +65 -31
  45. package/dist/vdi-snapshots/vdi-snapshot.controller.mjs +36 -6
  46. package/dist/vdis/vdi.controller.mjs +69 -8
  47. package/dist/vifs/vif.controller.mjs +43 -7
  48. package/dist/vm-controller/vm-controller.controller.mjs +62 -9
  49. package/dist/vm-snapshots/vm-snapshot.controller.mjs +70 -8
  50. package/dist/vm-templates/vm-template.controller.mjs +71 -8
  51. package/dist/vms/vm.controller.mjs +164 -12
  52. package/open-api/spec/swagger.json +10907 -3265
  53. 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, limit })), req);
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 on the given SR.
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, limit });
122
- return this.sendObjects(Object.values(messages), req, 'messages');
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, limit });
132
- return this.sendObjects(Object.values(tasks), req, 'tasks');
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, limit })), req);
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, limit });
66
- return this.sendObjects(Object.values(messages), req, 'messages');
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, limit });
76
- return this.sendObjects(Object.values(tasks), req, 'tasks');
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, limit })), req);
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, limit }), req, obj => obj.type.toLowerCase() + 's');
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, limit });
78
- return this.sendObjects(Object.values(messages), req, 'messages');
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, limit });
88
- return this.sendObjects(Object.values(tasks), req, 'tasks');
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())