@xen-orchestra/rest-api 0.28.2 → 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 +28 -3
- package/dist/abstract-classes/listener.mjs +124 -15
- 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 +25 -11
- package/dist/alarms/alarm.service.mjs +8 -0
- package/dist/backup-archives/backup-archive.controller.mjs +33 -23
- package/dist/backup-archives/backup-archive.service.mjs +21 -0
- package/dist/backup-jobs/backup-job.controller.mjs +74 -25
- package/dist/backup-jobs/backup-job.service.mjs +7 -0
- package/dist/backup-logs/backup-log.controller.mjs +28 -13
- package/dist/backup-logs/backup-log.service.mjs +19 -0
- package/dist/backup-repositories/backup-repositories.controller.mjs +24 -5
- package/dist/events/event.class.mjs +36 -18
- package/dist/events/event.controller.mjs +3 -0
- package/dist/events/event.service.mjs +4 -4
- package/dist/groups/group.controller.mjs +99 -12
- package/dist/helpers/markdown.helper.mjs +20 -0
- package/dist/helpers/object-wrapper.helper.mjs +3 -3
- package/dist/hosts/host.controller.mjs +90 -15
- package/dist/ioc/ioc.mjs +13 -4
- package/dist/messages/message.controller.mjs +32 -10
- 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 +72 -17
- 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 +856 -172
- package/dist/pbds/pbd.controller.mjs +20 -5
- package/dist/pcis/pci.controller.mjs +19 -5
- package/dist/pgpus/pgpu.controller.mjs +19 -5
- package/dist/pifs/pif.controller.mjs +56 -16
- package/dist/pools/pool.controller.mjs +166 -17
- package/dist/proxies/proxy.controller.mjs +25 -6
- package/dist/restore-logs/restore-log.controller.mjs +42 -23
- package/dist/schedules/schedule.controller.mjs +36 -5
- package/dist/servers/server.controller.mjs +71 -9
- package/dist/sms/sm.controller.mjs +17 -4
- package/dist/srs/sr.controller.mjs +74 -18
- package/dist/tasks/task.controller.mjs +74 -13
- package/dist/users/user.controller.mjs +124 -22
- package/dist/vbds/vbd.controller.mjs +76 -38
- package/dist/vdi-snapshots/vdi-snapshot.controller.mjs +48 -14
- package/dist/vdis/vdi.controller.mjs +81 -16
- package/dist/vifs/vif.controller.mjs +118 -16
- package/dist/vm-controller/vm-controller.controller.mjs +77 -19
- package/dist/vm-snapshots/vm-snapshot.controller.mjs +85 -18
- package/dist/vm-templates/vm-template.controller.mjs +86 -18
- package/dist/vms/vm.controller.mjs +182 -24
- package/open-api/spec/swagger.json +12112 -3537
- package/package.json +12 -11
|
@@ -12,10 +12,11 @@ import { json } from 'express';
|
|
|
12
12
|
import { inject } from 'inversify';
|
|
13
13
|
import { invalidParameters as invalidParametersError } from 'xo-common/api-errors.js';
|
|
14
14
|
import { provide } from 'inversify-binding-decorators';
|
|
15
|
+
import { acl } from '../middlewares/acl.middleware.mjs';
|
|
15
16
|
import { AlarmService } from '../alarms/alarm.service.mjs';
|
|
16
17
|
import { escapeUnsafeComplexMatcher } from '../helpers/utils.helper.mjs';
|
|
17
18
|
import { genericAlarmsExample } from '../open-api/oa-examples/alarm.oa-example.mjs';
|
|
18
|
-
import { asynchronousActionResp, badRequestResp, createdResp, internalServerErrorResp, invalidParameters, noContentResp, notFoundResp, unauthorizedResp, } from '../open-api/common/response.common.mjs';
|
|
19
|
+
import { asynchronousActionResp, badRequestResp, createdResp, internalServerErrorResp, invalidParameters, noContentResp, forbiddenOperationResp, notFoundResp, unauthorizedResp, } from '../open-api/common/response.common.mjs';
|
|
19
20
|
import { BASE_URL } from '../index.mjs';
|
|
20
21
|
import { partialVbds, vbd, vbdId, vbdIds } from '../open-api/oa-examples/vbd.oa-example.mjs';
|
|
21
22
|
import { RestApi } from '../rest-api/rest-api.mjs';
|
|
@@ -28,6 +29,29 @@ let VbdController = class VbdController extends XapiXoController {
|
|
|
28
29
|
super('VBD', restApi);
|
|
29
30
|
this.#alarmService = alarmService;
|
|
30
31
|
}
|
|
32
|
+
/**
|
|
33
|
+
* Returns all VBDs that match the following privilege:
|
|
34
|
+
* - resource: vbd, action: read
|
|
35
|
+
*
|
|
36
|
+
* @example fields "device,bootable,uuid"
|
|
37
|
+
* @example filter "!bootable?"
|
|
38
|
+
* @example limit 42
|
|
39
|
+
*/
|
|
40
|
+
getVbds(req, fields, ndjson, markdown, filter, limit) {
|
|
41
|
+
return this.sendObjects(Object.values(this.getObjects({ filter })), req, {
|
|
42
|
+
limit,
|
|
43
|
+
privilege: { action: 'read', resource: 'vbd' },
|
|
44
|
+
});
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Required privilege:
|
|
48
|
+
* - resource: vbd, action: read
|
|
49
|
+
*
|
|
50
|
+
* @example id "f07ab729-c0e8-721c-45ec-f11276377030"
|
|
51
|
+
*/
|
|
52
|
+
getVbd(id) {
|
|
53
|
+
return this.getObject(id);
|
|
54
|
+
}
|
|
31
55
|
/**
|
|
32
56
|
* Create a VBD to attach a VDI to a VM
|
|
33
57
|
*
|
|
@@ -51,22 +75,6 @@ let VbdController = class VbdController extends XapiXoController {
|
|
|
51
75
|
this.setHeader('Location', `${BASE_URL}/vbds/${vbdUuid}`);
|
|
52
76
|
return { id: vbdUuid };
|
|
53
77
|
}
|
|
54
|
-
/**
|
|
55
|
-
*
|
|
56
|
-
* @example fields "device,bootable,uuid"
|
|
57
|
-
* @example filter "!bootable?"
|
|
58
|
-
* @example limit 42
|
|
59
|
-
*/
|
|
60
|
-
getVbds(req, fields, ndjson, filter, limit) {
|
|
61
|
-
return this.sendObjects(Object.values(this.getObjects({ filter, limit })), req);
|
|
62
|
-
}
|
|
63
|
-
/**
|
|
64
|
-
*
|
|
65
|
-
* @example id "f07ab729-c0e8-721c-45ec-f11276377030"
|
|
66
|
-
*/
|
|
67
|
-
getVbd(id) {
|
|
68
|
-
return this.getObject(id);
|
|
69
|
-
}
|
|
70
78
|
/**
|
|
71
79
|
* Delete a VBD
|
|
72
80
|
*
|
|
@@ -80,38 +88,58 @@ let VbdController = class VbdController extends XapiXoController {
|
|
|
80
88
|
await xapiVbd.$xapi.VBD_destroy(xapiVbd.$ref);
|
|
81
89
|
}
|
|
82
90
|
/**
|
|
91
|
+
* Returns all alarms that match the following privilege:
|
|
92
|
+
* - resource: alarm, action: read
|
|
93
|
+
*
|
|
83
94
|
* @example id "f07ab729-c0e8-721c-45ec-f11276377030"
|
|
84
95
|
* @example fields "id,time"
|
|
85
96
|
* @example filter "time:>1747053793"
|
|
86
97
|
* @example limit 42
|
|
87
98
|
*/
|
|
88
|
-
getVbdAlarms(req, id, fields, ndjson, filter, limit) {
|
|
99
|
+
getVbdAlarms(req, id, fields, ndjson, markdown, filter, limit) {
|
|
89
100
|
const vbd = this.getObject(id);
|
|
90
101
|
const alarms = this.#alarmService.getAlarms({
|
|
91
102
|
filter: `${escapeUnsafeComplexMatcher(filter) ?? ''} object:uuid:${vbd.uuid}`,
|
|
103
|
+
});
|
|
104
|
+
return this.sendObjects(Object.values(alarms), req, {
|
|
105
|
+
path: 'alarms',
|
|
92
106
|
limit,
|
|
107
|
+
privilege: { action: 'read', resource: 'alarm' },
|
|
93
108
|
});
|
|
94
|
-
return this.sendObjects(Object.values(alarms), req, 'alarms');
|
|
95
109
|
}
|
|
96
110
|
/**
|
|
111
|
+
* Returns all messages that match the following privilege:
|
|
112
|
+
* - resource: message, action: read
|
|
113
|
+
*
|
|
97
114
|
* @example id "f07ab729-c0e8-721c-45ec-f11276377030"
|
|
98
115
|
* @example fields "name,id,$object"
|
|
99
116
|
* @example filter "name:VM_STARTED"
|
|
100
117
|
* @example limit 42
|
|
101
118
|
*/
|
|
102
|
-
getVbdMessages(req, id, fields, ndjson, filter, limit) {
|
|
103
|
-
const messages = this.getMessagesForObject(id, { filter
|
|
104
|
-
return this.sendObjects(Object.values(messages), req,
|
|
119
|
+
getVbdMessages(req, id, fields, ndjson, markdown, filter, limit) {
|
|
120
|
+
const messages = this.getMessagesForObject(id, { filter });
|
|
121
|
+
return this.sendObjects(Object.values(messages), req, {
|
|
122
|
+
path: 'messages',
|
|
123
|
+
limit,
|
|
124
|
+
privilege: { action: 'read', resource: 'message' },
|
|
125
|
+
});
|
|
105
126
|
}
|
|
106
127
|
/**
|
|
128
|
+
* Returns all tasks that match the following privilege:
|
|
129
|
+
* - resource: task, action: read
|
|
130
|
+
*
|
|
107
131
|
* @example id "f07ab729-c0e8-721c-45ec-f11276377030"
|
|
108
132
|
* @example fields "id,status,properties"
|
|
109
133
|
* @example filter "status:failure"
|
|
110
134
|
* @example limit 42
|
|
111
135
|
*/
|
|
112
|
-
async getVbdTasks(req, id, fields, ndjson, filter, limit) {
|
|
113
|
-
const tasks = await this.getTasksForObject(id, { filter
|
|
114
|
-
return this.sendObjects(Object.values(tasks), req,
|
|
136
|
+
async getVbdTasks(req, id, fields, ndjson, markdown, filter, limit) {
|
|
137
|
+
const tasks = await this.getTasksForObject(id, { filter });
|
|
138
|
+
return this.sendObjects(Object.values(tasks), req, {
|
|
139
|
+
path: 'tasks',
|
|
140
|
+
limit,
|
|
141
|
+
privilege: { action: 'read', resource: 'task' },
|
|
142
|
+
});
|
|
115
143
|
}
|
|
116
144
|
/**
|
|
117
145
|
* Hotplug the VBD, dynamically attaching it to the running VM
|
|
@@ -152,31 +180,35 @@ let VbdController = class VbdController extends XapiXoController {
|
|
|
152
180
|
});
|
|
153
181
|
}
|
|
154
182
|
};
|
|
155
|
-
__decorate([
|
|
156
|
-
Example(vbdId),
|
|
157
|
-
Post(''),
|
|
158
|
-
Middlewares(json()),
|
|
159
|
-
SuccessResponse(createdResp.status, createdResp.description),
|
|
160
|
-
Response(notFoundResp.status, notFoundResp.description),
|
|
161
|
-
Response(invalidParameters.status, invalidParameters.description),
|
|
162
|
-
__param(0, Body())
|
|
163
|
-
], VbdController.prototype, "createVbd", null);
|
|
164
183
|
__decorate([
|
|
165
184
|
Example(vbdIds),
|
|
166
185
|
Example(partialVbds),
|
|
167
186
|
Get(''),
|
|
187
|
+
Security('*', ['acl']),
|
|
168
188
|
__param(0, Request()),
|
|
169
189
|
__param(1, Query()),
|
|
170
190
|
__param(2, Query()),
|
|
171
191
|
__param(3, Query()),
|
|
172
|
-
__param(4, Query())
|
|
192
|
+
__param(4, Query()),
|
|
193
|
+
__param(5, Query())
|
|
173
194
|
], VbdController.prototype, "getVbds", null);
|
|
174
195
|
__decorate([
|
|
175
196
|
Example(vbd),
|
|
176
197
|
Get('{id}'),
|
|
198
|
+
Middlewares(acl({ resource: 'vbd', action: 'read', objectId: 'params.id' })),
|
|
199
|
+
Response(forbiddenOperationResp.status, forbiddenOperationResp.description),
|
|
177
200
|
Response(notFoundResp.status, notFoundResp.description),
|
|
178
201
|
__param(0, Path())
|
|
179
202
|
], VbdController.prototype, "getVbd", null);
|
|
203
|
+
__decorate([
|
|
204
|
+
Example(vbdId),
|
|
205
|
+
Post(''),
|
|
206
|
+
Middlewares(json()),
|
|
207
|
+
SuccessResponse(createdResp.status, createdResp.description),
|
|
208
|
+
Response(notFoundResp.status, notFoundResp.description),
|
|
209
|
+
Response(invalidParameters.status, invalidParameters.description),
|
|
210
|
+
__param(0, Body())
|
|
211
|
+
], VbdController.prototype, "createVbd", null);
|
|
180
212
|
__decorate([
|
|
181
213
|
Delete('{id}'),
|
|
182
214
|
SuccessResponse(noContentResp.status, noContentResp.description),
|
|
@@ -186,6 +218,7 @@ __decorate([
|
|
|
186
218
|
__decorate([
|
|
187
219
|
Example(genericAlarmsExample),
|
|
188
220
|
Get('{id}/alarms'),
|
|
221
|
+
Security('*', ['acl']),
|
|
189
222
|
Tags('alarms'),
|
|
190
223
|
Response(notFoundResp.status, notFoundResp.description),
|
|
191
224
|
__param(0, Request()),
|
|
@@ -193,12 +226,14 @@ __decorate([
|
|
|
193
226
|
__param(2, Query()),
|
|
194
227
|
__param(3, Query()),
|
|
195
228
|
__param(4, Query()),
|
|
196
|
-
__param(5, Query())
|
|
229
|
+
__param(5, Query()),
|
|
230
|
+
__param(6, Query())
|
|
197
231
|
], VbdController.prototype, "getVbdAlarms", null);
|
|
198
232
|
__decorate([
|
|
199
233
|
Example(messageIds),
|
|
200
234
|
Example(partialMessages),
|
|
201
235
|
Get('{id}/messages'),
|
|
236
|
+
Security('*', ['acl']),
|
|
202
237
|
Tags('messages'),
|
|
203
238
|
Response(notFoundResp.status, notFoundResp.description),
|
|
204
239
|
__param(0, Request()),
|
|
@@ -206,12 +241,14 @@ __decorate([
|
|
|
206
241
|
__param(2, Query()),
|
|
207
242
|
__param(3, Query()),
|
|
208
243
|
__param(4, Query()),
|
|
209
|
-
__param(5, Query())
|
|
244
|
+
__param(5, Query()),
|
|
245
|
+
__param(6, Query())
|
|
210
246
|
], VbdController.prototype, "getVbdMessages", null);
|
|
211
247
|
__decorate([
|
|
212
248
|
Example(taskIds),
|
|
213
249
|
Example(partialTasks),
|
|
214
250
|
Get('{id}/tasks'),
|
|
251
|
+
Security('*', ['acl']),
|
|
215
252
|
Tags('tasks'),
|
|
216
253
|
Response(notFoundResp.status, notFoundResp.description),
|
|
217
254
|
__param(0, Request()),
|
|
@@ -219,7 +256,8 @@ __decorate([
|
|
|
219
256
|
__param(2, Query()),
|
|
220
257
|
__param(3, Query()),
|
|
221
258
|
__param(4, Query()),
|
|
222
|
-
__param(5, Query())
|
|
259
|
+
__param(5, Query()),
|
|
260
|
+
__param(6, Query())
|
|
223
261
|
], VbdController.prototype, "getVbdTasks", null);
|
|
224
262
|
__decorate([
|
|
225
263
|
Example(taskLocation),
|
|
@@ -29,12 +29,18 @@ let VdiSnapshotController = class VdiSnapshotController extends XapiXoController
|
|
|
29
29
|
this.#vdiService = vdiService;
|
|
30
30
|
}
|
|
31
31
|
/**
|
|
32
|
+
* Returns all VDI snapshots that match the following privilege:
|
|
33
|
+
* - resource: vdi-snapshot, action: read
|
|
34
|
+
*
|
|
32
35
|
* @example fields "uuid,snapshot_time,$snapshot_of"
|
|
33
36
|
* @example filter "snapshot_time:>1725020038"
|
|
34
37
|
* @example limit 42
|
|
35
38
|
*/
|
|
36
|
-
getVdiSnapshots(req, fields, ndjson, filter, limit) {
|
|
37
|
-
return this.sendObjects(Object.values(this.getObjects({ filter
|
|
39
|
+
getVdiSnapshots(req, fields, ndjson, markdown, filter, limit) {
|
|
40
|
+
return this.sendObjects(Object.values(this.getObjects({ filter })), req, {
|
|
41
|
+
limit,
|
|
42
|
+
privilege: { action: 'read', resource: 'vdi-snapshot' },
|
|
43
|
+
});
|
|
38
44
|
}
|
|
39
45
|
/**
|
|
40
46
|
*
|
|
@@ -59,18 +65,24 @@ let VdiSnapshotController = class VdiSnapshotController extends XapiXoController
|
|
|
59
65
|
return this.getObject(id);
|
|
60
66
|
}
|
|
61
67
|
/**
|
|
68
|
+
* Returns all alarms that match the following privilege:
|
|
69
|
+
* - resource: alarm, action: read
|
|
70
|
+
*
|
|
62
71
|
* @example id "d2727772-735b-478f-b6f9-11e7db56dfd0"
|
|
63
72
|
* @example fields "id,time"
|
|
64
73
|
* @example filter "time:>1747053793"
|
|
65
74
|
* @example limit 42
|
|
66
75
|
*/
|
|
67
|
-
getVdiSnapshotAlarms(req, id, fields, ndjson, filter, limit) {
|
|
76
|
+
getVdiSnapshotAlarms(req, id, fields, ndjson, markdown, filter, limit) {
|
|
68
77
|
const vdiSnapshot = this.getObject(id);
|
|
69
78
|
const alarms = this.#alarmService.getAlarms({
|
|
70
79
|
filter: `${escapeUnsafeComplexMatcher(filter) ?? ''} object:uuid:${vdiSnapshot.uuid}`,
|
|
80
|
+
});
|
|
81
|
+
return this.sendObjects(Object.values(alarms), req, {
|
|
82
|
+
path: 'alarms',
|
|
71
83
|
limit,
|
|
84
|
+
privilege: { action: 'read', resource: 'alarm' },
|
|
72
85
|
});
|
|
73
|
-
return this.sendObjects(Object.values(alarms), req, 'alarms');
|
|
74
86
|
}
|
|
75
87
|
/**
|
|
76
88
|
* @example id "d2727772-735b-478f-b6f9-11e7db56dfd0"
|
|
@@ -80,24 +92,38 @@ let VdiSnapshotController = class VdiSnapshotController extends XapiXoController
|
|
|
80
92
|
await xapiVdiSnapshot.$xapi.VDI_destroy(xapiVdiSnapshot.$ref);
|
|
81
93
|
}
|
|
82
94
|
/**
|
|
95
|
+
* Returns all messages that match the following privilege:
|
|
96
|
+
* - resource: message, action: read
|
|
97
|
+
*
|
|
83
98
|
* @example id "d2727772-735b-478f-b6f9-11e7db56dfd0"
|
|
84
99
|
* @example fields "name,id,$object"
|
|
85
100
|
* @example filter "name:VM_STARTED"
|
|
86
101
|
* @example limit 42
|
|
87
102
|
*/
|
|
88
|
-
getVdiSnapshotMessages(req, id, fields, ndjson, filter, limit) {
|
|
89
|
-
const messages = this.getMessagesForObject(id, { filter
|
|
90
|
-
return this.sendObjects(Object.values(messages), req,
|
|
103
|
+
getVdiSnapshotMessages(req, id, fields, ndjson, markdown, filter, limit) {
|
|
104
|
+
const messages = this.getMessagesForObject(id, { filter });
|
|
105
|
+
return this.sendObjects(Object.values(messages), req, {
|
|
106
|
+
path: 'messages',
|
|
107
|
+
limit,
|
|
108
|
+
privilege: { action: 'read', resource: 'message' },
|
|
109
|
+
});
|
|
91
110
|
}
|
|
92
111
|
/**
|
|
112
|
+
* Returns all tasks that match the following privilege:
|
|
113
|
+
* - resource: task, action: read
|
|
114
|
+
*
|
|
93
115
|
* @example id "d2727772-735b-478f-b6f9-11e7db56dfd0"
|
|
94
116
|
* @example fields "id,status,properties"
|
|
95
117
|
* @example filter "status:failure"
|
|
96
118
|
* @example limit 42
|
|
97
119
|
*/
|
|
98
|
-
async getVdiSnapshotTasks(req, id, fields, ndjson, filter, limit) {
|
|
99
|
-
const tasks = await this.getTasksForObject(id, { filter
|
|
100
|
-
return this.sendObjects(Object.values(tasks), req,
|
|
120
|
+
async getVdiSnapshotTasks(req, id, fields, ndjson, markdown, filter, limit) {
|
|
121
|
+
const tasks = await this.getTasksForObject(id, { filter });
|
|
122
|
+
return this.sendObjects(Object.values(tasks), req, {
|
|
123
|
+
path: 'tasks',
|
|
124
|
+
limit,
|
|
125
|
+
privilege: { action: 'read', resource: 'task' },
|
|
126
|
+
});
|
|
101
127
|
}
|
|
102
128
|
/**
|
|
103
129
|
* @example id "d2727772-735b-478f-b6f9-11e7db56dfd0"
|
|
@@ -120,11 +146,13 @@ __decorate([
|
|
|
120
146
|
Example(vdiSnapshotIds),
|
|
121
147
|
Example(partialVdiSnapshots),
|
|
122
148
|
Get(''),
|
|
149
|
+
Security('*', ['acl']),
|
|
123
150
|
__param(0, Request()),
|
|
124
151
|
__param(1, Query()),
|
|
125
152
|
__param(2, Query()),
|
|
126
153
|
__param(3, Query()),
|
|
127
|
-
__param(4, Query())
|
|
154
|
+
__param(4, Query()),
|
|
155
|
+
__param(5, Query())
|
|
128
156
|
], VdiSnapshotController.prototype, "getVdiSnapshots", null);
|
|
129
157
|
__decorate([
|
|
130
158
|
Get('{id}.{format}'),
|
|
@@ -144,6 +172,7 @@ __decorate([
|
|
|
144
172
|
__decorate([
|
|
145
173
|
Example(genericAlarmsExample),
|
|
146
174
|
Get('{id}/alarms'),
|
|
175
|
+
Security('*', ['acl']),
|
|
147
176
|
Tags('alarms'),
|
|
148
177
|
Response(notFoundResp.status, notFoundResp.description),
|
|
149
178
|
__param(0, Request()),
|
|
@@ -151,7 +180,8 @@ __decorate([
|
|
|
151
180
|
__param(2, Query()),
|
|
152
181
|
__param(3, Query()),
|
|
153
182
|
__param(4, Query()),
|
|
154
|
-
__param(5, Query())
|
|
183
|
+
__param(5, Query()),
|
|
184
|
+
__param(6, Query())
|
|
155
185
|
], VdiSnapshotController.prototype, "getVdiSnapshotAlarms", null);
|
|
156
186
|
__decorate([
|
|
157
187
|
Delete('{id}'),
|
|
@@ -163,6 +193,7 @@ __decorate([
|
|
|
163
193
|
Example(messageIds),
|
|
164
194
|
Example(partialMessages),
|
|
165
195
|
Get('{id}/messages'),
|
|
196
|
+
Security('*', ['acl']),
|
|
166
197
|
Tags('messages'),
|
|
167
198
|
Response(notFoundResp.status, notFoundResp.description),
|
|
168
199
|
__param(0, Request()),
|
|
@@ -170,12 +201,14 @@ __decorate([
|
|
|
170
201
|
__param(2, Query()),
|
|
171
202
|
__param(3, Query()),
|
|
172
203
|
__param(4, Query()),
|
|
173
|
-
__param(5, Query())
|
|
204
|
+
__param(5, Query()),
|
|
205
|
+
__param(6, Query())
|
|
174
206
|
], VdiSnapshotController.prototype, "getVdiSnapshotMessages", null);
|
|
175
207
|
__decorate([
|
|
176
208
|
Example(taskIds),
|
|
177
209
|
Example(partialTasks),
|
|
178
210
|
Get('{id}/tasks'),
|
|
211
|
+
Security('*', ['acl']),
|
|
179
212
|
Tags('tasks'),
|
|
180
213
|
Response(notFoundResp.status, notFoundResp.description),
|
|
181
214
|
__param(0, Request()),
|
|
@@ -183,7 +216,8 @@ __decorate([
|
|
|
183
216
|
__param(2, Query()),
|
|
184
217
|
__param(3, Query()),
|
|
185
218
|
__param(4, Query()),
|
|
186
|
-
__param(5, Query())
|
|
219
|
+
__param(5, Query()),
|
|
220
|
+
__param(6, Query())
|
|
187
221
|
], VdiSnapshotController.prototype, "getVdiSnapshotTasks", null);
|
|
188
222
|
__decorate([
|
|
189
223
|
Put('{id}/tags/{tag}'),
|
|
@@ -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
|
-
getVdis(req, fields, ndjson, filter, limit) {
|
|
39
|
-
return this.sendObjects(Object.values(this.getObjects({ filter
|
|
42
|
+
getVdis(req, fields, ndjson, markdown, filter, limit) {
|
|
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,27 +79,36 @@ 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"
|
|
78
97
|
* @example limit 42
|
|
79
98
|
*/
|
|
80
|
-
getVdiAlarms(req, id, fields, ndjson, filter, limit) {
|
|
99
|
+
getVdiAlarms(req, id, fields, ndjson, markdown, filter, limit) {
|
|
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
|
-
getVdiMessages(req, id, fields, ndjson, filter, limit) {
|
|
121
|
-
const messages = this.getMessagesForObject(id, { filter
|
|
122
|
-
return this.sendObjects(Object.values(messages), req,
|
|
148
|
+
getVdiMessages(req, id, fields, ndjson, markdown, filter, limit) {
|
|
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
|
-
async getVdiTasks(req, id, fields, ndjson, filter, limit) {
|
|
131
|
-
const tasks = await this.getTasksForObject(id, { filter
|
|
132
|
-
return this.sendObjects(Object.values(tasks), req,
|
|
165
|
+
async getVdiTasks(req, id, fields, ndjson, markdown, filter, limit) {
|
|
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,15 +218,19 @@ __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()),
|
|
179
225
|
__param(3, Query()),
|
|
180
|
-
__param(4, Query())
|
|
226
|
+
__param(4, Query()),
|
|
227
|
+
__param(5, Query())
|
|
181
228
|
], VdiController.prototype, "getVdis", null);
|
|
182
229
|
__decorate([
|
|
183
230
|
Get('{id}.{format}'),
|
|
231
|
+
Middlewares(acl({ resource: 'vdi', action: 'export-content', objectId: 'params.id' })),
|
|
184
232
|
SuccessResponse(200, 'Download started', 'application/octet-stream'),
|
|
233
|
+
Response(forbiddenOperationResp.status, forbiddenOperationResp.description),
|
|
185
234
|
Response(notFoundResp.status, notFoundResp.description),
|
|
186
235
|
Response(422, 'Invalid format'),
|
|
187
236
|
__param(0, Request()),
|
|
@@ -190,7 +239,9 @@ __decorate([
|
|
|
190
239
|
], VdiController.prototype, "exportVdiContent", null);
|
|
191
240
|
__decorate([
|
|
192
241
|
Put('{id}.{format}'),
|
|
242
|
+
Middlewares(acl({ resource: 'vdi', action: 'import-content', objectId: 'params.id' })),
|
|
193
243
|
SuccessResponse(noContentResp.status, noContentResp.description),
|
|
244
|
+
Response(forbiddenOperationResp.status, forbiddenOperationResp.description),
|
|
194
245
|
Response(notFoundResp.status, notFoundResp.description),
|
|
195
246
|
Response(422, 'Invalid format'),
|
|
196
247
|
Response(internalServerErrorResp.status, internalServerErrorResp.description),
|
|
@@ -201,12 +252,15 @@ __decorate([
|
|
|
201
252
|
__decorate([
|
|
202
253
|
Example(vdi),
|
|
203
254
|
Get('{id}'),
|
|
255
|
+
Middlewares(acl({ resource: 'vdi', action: 'read', objectId: 'params.id' })),
|
|
256
|
+
Response(forbiddenOperationResp.status, forbiddenOperationResp.description),
|
|
204
257
|
Response(notFoundResp.status, notFoundResp.description),
|
|
205
258
|
__param(0, Path())
|
|
206
259
|
], VdiController.prototype, "getVdi", null);
|
|
207
260
|
__decorate([
|
|
208
261
|
Example(genericAlarmsExample),
|
|
209
262
|
Get('{id}/alarms'),
|
|
263
|
+
Security('*', ['acl']),
|
|
210
264
|
Tags('alarms'),
|
|
211
265
|
Response(notFoundResp.status, notFoundResp.description),
|
|
212
266
|
__param(0, Request()),
|
|
@@ -214,7 +268,8 @@ __decorate([
|
|
|
214
268
|
__param(2, Query()),
|
|
215
269
|
__param(3, Query()),
|
|
216
270
|
__param(4, Query()),
|
|
217
|
-
__param(5, Query())
|
|
271
|
+
__param(5, Query()),
|
|
272
|
+
__param(6, Query())
|
|
218
273
|
], VdiController.prototype, "getVdiAlarms", null);
|
|
219
274
|
__decorate([
|
|
220
275
|
Example(vdiId),
|
|
@@ -227,7 +282,9 @@ __decorate([
|
|
|
227
282
|
], VdiController.prototype, "createVdi", null);
|
|
228
283
|
__decorate([
|
|
229
284
|
Delete('{id}'),
|
|
285
|
+
Middlewares(acl({ resource: 'vdi', action: 'delete', objectId: 'params.id' })),
|
|
230
286
|
SuccessResponse(noContentResp.status, noContentResp.description),
|
|
287
|
+
Response(forbiddenOperationResp.status, forbiddenOperationResp.description),
|
|
231
288
|
Response(notFoundResp.status, notFoundResp.description),
|
|
232
289
|
__param(0, Path())
|
|
233
290
|
], VdiController.prototype, "deleteVdi", null);
|
|
@@ -235,6 +292,7 @@ __decorate([
|
|
|
235
292
|
Example(messageIds),
|
|
236
293
|
Example(partialMessages),
|
|
237
294
|
Get('{id}/messages'),
|
|
295
|
+
Security('*', ['acl']),
|
|
238
296
|
Tags('messages'),
|
|
239
297
|
Response(notFoundResp.status, notFoundResp.description),
|
|
240
298
|
__param(0, Request()),
|
|
@@ -242,12 +300,14 @@ __decorate([
|
|
|
242
300
|
__param(2, Query()),
|
|
243
301
|
__param(3, Query()),
|
|
244
302
|
__param(4, Query()),
|
|
245
|
-
__param(5, Query())
|
|
303
|
+
__param(5, Query()),
|
|
304
|
+
__param(6, Query())
|
|
246
305
|
], VdiController.prototype, "getVdiMessages", null);
|
|
247
306
|
__decorate([
|
|
248
307
|
Example(taskIds),
|
|
249
308
|
Example(partialTasks),
|
|
250
309
|
Get('{id}/tasks'),
|
|
310
|
+
Security('*', ['acl']),
|
|
251
311
|
Tags('tasks'),
|
|
252
312
|
Response(notFoundResp.status, notFoundResp.description),
|
|
253
313
|
__param(0, Request()),
|
|
@@ -255,7 +315,8 @@ __decorate([
|
|
|
255
315
|
__param(2, Query()),
|
|
256
316
|
__param(3, Query()),
|
|
257
317
|
__param(4, Query()),
|
|
258
|
-
__param(5, Query())
|
|
318
|
+
__param(5, Query()),
|
|
319
|
+
__param(6, Query())
|
|
259
320
|
], VdiController.prototype, "getVdiTasks", null);
|
|
260
321
|
__decorate([
|
|
261
322
|
Example(taskLocation),
|
|
@@ -272,14 +333,18 @@ __decorate([
|
|
|
272
333
|
], VdiController.prototype, "migrateVdi", null);
|
|
273
334
|
__decorate([
|
|
274
335
|
Put('{id}/tags/{tag}'),
|
|
336
|
+
Middlewares(acl({ resource: 'vdi', action: 'update:tags', objectId: 'params.id' })),
|
|
275
337
|
SuccessResponse(noContentResp.status, noContentResp.description),
|
|
338
|
+
Response(forbiddenOperationResp.status, forbiddenOperationResp.description),
|
|
276
339
|
Response(notFoundResp.status, notFoundResp.description),
|
|
277
340
|
__param(0, Path()),
|
|
278
341
|
__param(1, Path())
|
|
279
342
|
], VdiController.prototype, "putVdiTag", null);
|
|
280
343
|
__decorate([
|
|
281
344
|
Delete('{id}/tags/{tag}'),
|
|
345
|
+
Middlewares(acl({ resource: 'vdi', action: 'update:tags', objectId: 'params.id' })),
|
|
282
346
|
SuccessResponse(noContentResp.status, noContentResp.description),
|
|
347
|
+
Response(forbiddenOperationResp.status, forbiddenOperationResp.description),
|
|
283
348
|
Response(notFoundResp.status, notFoundResp.description),
|
|
284
349
|
__param(0, Path()),
|
|
285
350
|
__param(1, Path())
|