@xen-orchestra/rest-api 0.23.0 → 0.24.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/events/event.class.mjs +31 -22
- package/dist/events/event.service.mjs +21 -4
- package/dist/helpers/object-wrapper.helper.mjs +9 -4
- package/dist/middlewares/authentication.middleware.mjs +1 -1
- package/dist/open-api/oa-examples/vif.oa-example.mjs +1 -0
- package/dist/open-api/routes/routes.js +161 -2
- package/dist/pools/pool.controller.mjs +12 -3
- package/dist/pools/pool.service.mjs +1 -1
- package/dist/vbds/vbd.controller.mjs +60 -2
- package/dist/vdis/vdi.controller.mjs +39 -4
- package/dist/vifs/vif.controller.mjs +53 -3
- package/open-api/spec/swagger.json +483 -22
- package/package.json +4 -4
|
@@ -19,31 +19,35 @@ export class Subscriber {
|
|
|
19
19
|
get connection() {
|
|
20
20
|
return this.#connection;
|
|
21
21
|
}
|
|
22
|
-
constructor(
|
|
22
|
+
constructor(connection, manager) {
|
|
23
23
|
this.#id = crypto.randomUUID();
|
|
24
|
-
|
|
25
|
-
'Content-Type': 'text/event-stream',
|
|
26
|
-
Connection: 'keep-alive',
|
|
27
|
-
'Cache-Control': 'no-cache, no-transform',
|
|
28
|
-
});
|
|
29
|
-
res.setHeaders(headers);
|
|
30
|
-
res.on('close', () => this.clear());
|
|
24
|
+
connection.on('close', () => this.clear());
|
|
31
25
|
manager.addSubscriber(this);
|
|
32
|
-
this.#connection =
|
|
26
|
+
this.#connection = connection;
|
|
33
27
|
this.#manager = manager;
|
|
34
28
|
this.#isAlive = true;
|
|
35
29
|
}
|
|
30
|
+
#safeWrite(payload) {
|
|
31
|
+
const ok = this.#connection.write(payload);
|
|
32
|
+
if (!ok) {
|
|
33
|
+
log.error(`Too much data in queue for the client ${this.id} (${Math.round(this.#connection.writableLength / 1024 / 1024)} MB). The connection is going to be destroyed`);
|
|
34
|
+
this.clear();
|
|
35
|
+
}
|
|
36
|
+
}
|
|
36
37
|
broadcast(event, data) {
|
|
37
38
|
if (!this.#isAlive) {
|
|
38
39
|
log.warn('broadcast called on a subscriber that is not alive, but still in memory! Force clear and do nothing');
|
|
39
40
|
this.clear();
|
|
40
41
|
return;
|
|
41
42
|
}
|
|
42
|
-
|
|
43
|
-
this.#
|
|
43
|
+
const payload = `event: ${event}\ndata: ${JSON.stringify(data)}\n\n`;
|
|
44
|
+
this.#safeWrite(payload);
|
|
44
45
|
}
|
|
45
46
|
clear() {
|
|
46
47
|
this.#isAlive = false;
|
|
48
|
+
if (!this.#connection.closed || !this.#connection.destroyed) {
|
|
49
|
+
this.#connection.destroy();
|
|
50
|
+
}
|
|
47
51
|
this.#manager.removeSubscriber(this.id);
|
|
48
52
|
}
|
|
49
53
|
}
|
|
@@ -58,20 +62,25 @@ export class XoListener extends Listener {
|
|
|
58
62
|
handleData({ fields, event }, object, previousObj) {
|
|
59
63
|
let _object = object;
|
|
60
64
|
let _prevObject = previousObj;
|
|
61
|
-
if (this.#type === 'alarm') {
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
65
|
+
if (this.#type === 'alarm' || this.#type === 'message') {
|
|
66
|
+
const isAlarm = (object) => object !== undefined && 'type' in object && object.type === 'message' && this.#alarmService.isAlarm(object);
|
|
67
|
+
const objectIsAlarm = isAlarm(object);
|
|
68
|
+
const prevObjectIsAlarm = isAlarm(previousObj);
|
|
69
|
+
// If we are in an alarm listener and the objects are messages
|
|
70
|
+
// we clean them to ensure they are not sent via the SSE
|
|
71
|
+
// Same if we are in a message listener and the objects are alarms
|
|
72
|
+
if (this.#type === 'alarm') {
|
|
73
|
+
_object = objectIsAlarm ? this.#alarmService.parseAlarm(object) : undefined;
|
|
74
|
+
_prevObject = prevObjectIsAlarm ? this.#alarmService.parseAlarm(previousObj) : undefined;
|
|
67
75
|
}
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
this.#alarmService?.isAlarm(previousObj)) {
|
|
72
|
-
_prevObject = this.#alarmService.parseAlarm(previousObj);
|
|
76
|
+
else {
|
|
77
|
+
_object = objectIsAlarm ? undefined : object;
|
|
78
|
+
_prevObject = prevObjectIsAlarm ? undefined : object;
|
|
73
79
|
}
|
|
74
80
|
}
|
|
81
|
+
if (_object === undefined && _prevObject === undefined) {
|
|
82
|
+
return;
|
|
83
|
+
}
|
|
75
84
|
if (fields !== '*') {
|
|
76
85
|
if (_object !== undefined) {
|
|
77
86
|
_object = pick(_object, fields);
|
|
@@ -1,4 +1,6 @@
|
|
|
1
|
+
import os from 'node:os';
|
|
1
2
|
import { createLogger } from '@xen-orchestra/log';
|
|
3
|
+
import { PassThrough, pipeline } from 'node:stream';
|
|
2
4
|
import { PingListener, Subscriber, SubscriberManager, XoListener } from './event.class.mjs';
|
|
3
5
|
import { AlarmService } from '../alarms/alarm.service.mjs';
|
|
4
6
|
const log = createLogger('xo:rest-api:event-service');
|
|
@@ -26,7 +28,7 @@ export class EventService {
|
|
|
26
28
|
listener = new PingListener();
|
|
27
29
|
}
|
|
28
30
|
else {
|
|
29
|
-
const
|
|
31
|
+
const isMessage = type === 'alarm' || type === 'message';
|
|
30
32
|
let eventEmitter;
|
|
31
33
|
if (type === 'task') {
|
|
32
34
|
eventEmitter = this.#restApi.xoApp.tasks;
|
|
@@ -34,15 +36,30 @@ export class EventService {
|
|
|
34
36
|
else {
|
|
35
37
|
// alarm is purely XO-related; it doesn't exist at the XAPI level.
|
|
36
38
|
// alarm is a message with parsed values. So, in the case of an alarm listener, it listens for message collection.
|
|
37
|
-
eventEmitter = this.#restApi.xoApp.objects.allIndexes.type.getEventEmitterByType(
|
|
39
|
+
eventEmitter = this.#restApi.xoApp.objects.allIndexes.type.getEventEmitterByType(isMessage ? 'message' : type);
|
|
38
40
|
}
|
|
39
|
-
listener = new XoListener(type, eventEmitter,
|
|
41
|
+
listener = new XoListener(type, eventEmitter, isMessage ? this.#alarmService : undefined);
|
|
40
42
|
}
|
|
41
43
|
this.#listeners.set(type, listener);
|
|
42
44
|
return listener;
|
|
43
45
|
}
|
|
44
46
|
createSseSubscriber(res) {
|
|
45
|
-
const
|
|
47
|
+
const headers = new Headers({
|
|
48
|
+
'Content-Type': 'text/event-stream',
|
|
49
|
+
Connection: 'keep-alive',
|
|
50
|
+
'Cache-Control': 'no-cache, no-transform',
|
|
51
|
+
});
|
|
52
|
+
res.setHeaders(headers);
|
|
53
|
+
const maxRam = this.#restApi.xoApp.config.get('rest-api.percentOfRamAllocatedPerSseClient');
|
|
54
|
+
const connection = new PassThrough({
|
|
55
|
+
highWaterMark: Math.round(os.totalmem() * (maxRam / 100)),
|
|
56
|
+
});
|
|
57
|
+
pipeline(connection, res, error => {
|
|
58
|
+
if (error?.code !== 'ERR_STREAM_PREMATURE_CLOSE') {
|
|
59
|
+
log.error(error);
|
|
60
|
+
}
|
|
61
|
+
});
|
|
62
|
+
const subscriber = new Subscriber(connection, this.#subscriberManager);
|
|
46
63
|
subscriber.broadcast('init', { id: subscriber.id });
|
|
47
64
|
this.addListenerFor(subscriber.id, { type: 'ping' });
|
|
48
65
|
log.debug(`new SSE subscriber added: ${subscriber.id}`);
|
|
@@ -1,7 +1,5 @@
|
|
|
1
|
-
import path from 'node:path';
|
|
2
1
|
import pick from 'lodash/pick.js';
|
|
3
2
|
import { BASE_URL } from '../index.mjs';
|
|
4
|
-
const { join } = path.posix;
|
|
5
3
|
export function makeObjectMapper(req, path) {
|
|
6
4
|
const makeUrl = (obj) => {
|
|
7
5
|
let _path;
|
|
@@ -9,9 +7,16 @@ export function makeObjectMapper(req, path) {
|
|
|
9
7
|
_path = req.path;
|
|
10
8
|
}
|
|
11
9
|
else {
|
|
12
|
-
|
|
10
|
+
let tmpPath = typeof path === 'string' ? path : path(obj);
|
|
11
|
+
if (tmpPath.startsWith('/')) {
|
|
12
|
+
tmpPath = tmpPath.slice(1);
|
|
13
|
+
}
|
|
14
|
+
if (tmpPath.endsWith('/')) {
|
|
15
|
+
tmpPath = tmpPath.slice(0, -1);
|
|
16
|
+
}
|
|
17
|
+
_path = `${BASE_URL}/${tmpPath}`;
|
|
13
18
|
}
|
|
14
|
-
return
|
|
19
|
+
return `${_path}/${String(obj.id)}`;
|
|
15
20
|
};
|
|
16
21
|
let objectMapper;
|
|
17
22
|
const { query } = req;
|
|
@@ -51,7 +51,7 @@ export function setupApiContext(xoApp) {
|
|
|
51
51
|
res.locals.authType = 'basic';
|
|
52
52
|
}
|
|
53
53
|
try {
|
|
54
|
-
const { user } = await xoApp.authenticateUser(credentials, { ip });
|
|
54
|
+
const { user } = await xoApp.authenticateUser(credentials, { ip }, { bypassTaskCreation: hasToken });
|
|
55
55
|
return xoApp.runWithApiContext(user, next);
|
|
56
56
|
}
|
|
57
57
|
catch (error) {
|
|
@@ -493,6 +493,21 @@ const models = {
|
|
|
493
493
|
"type": { "ref": "Unbrand_XoVif_", "validators": {} },
|
|
494
494
|
},
|
|
495
495
|
// WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa
|
|
496
|
+
"Pick_CreateVifParams_91_0_93_.Exclude_keyofCreateVifParams_91_0_93_.network-or-VM__": {
|
|
497
|
+
"dataType": "refAlias",
|
|
498
|
+
"type": { "dataType": "nestedObjectLiteral", "nestedProperties": { "other_config": { "dataType": "union", "subSchemas": [{ "ref": "Record_string.string_" }, { "dataType": "undefined" }] }, "device": { "dataType": "union", "subSchemas": [{ "dataType": "string" }, { "dataType": "undefined" }] }, "MTU": { "dataType": "union", "subSchemas": [{ "dataType": "double" }, { "dataType": "undefined" }] }, "currently_attached": { "dataType": "union", "subSchemas": [{ "dataType": "boolean" }, { "dataType": "undefined" }] }, "ipv4_allowed": { "dataType": "union", "subSchemas": [{ "dataType": "array", "array": { "dataType": "string" } }, { "dataType": "undefined" }] }, "ipv6_allowed": { "dataType": "union", "subSchemas": [{ "dataType": "array", "array": { "dataType": "string" } }, { "dataType": "undefined" }] }, "locking_mode": { "dataType": "union", "subSchemas": [{ "ref": "VIF_LOCKING_MODE" }, { "dataType": "undefined" }] }, "qos_algorithm_params": { "dataType": "union", "subSchemas": [{ "ref": "Record_string.string_" }, { "dataType": "undefined" }] }, "qos_algorithm_type": { "dataType": "union", "subSchemas": [{ "dataType": "string" }, { "dataType": "undefined" }] } }, "validators": {} },
|
|
499
|
+
},
|
|
500
|
+
// WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa
|
|
501
|
+
"Omit_CreateVifParams_91_0_93_.network-or-VM_": {
|
|
502
|
+
"dataType": "refAlias",
|
|
503
|
+
"type": { "ref": "Pick_CreateVifParams_91_0_93_.Exclude_keyofCreateVifParams_91_0_93_.network-or-VM__", "validators": {} },
|
|
504
|
+
},
|
|
505
|
+
// WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa
|
|
506
|
+
"CreateVifBody": {
|
|
507
|
+
"dataType": "refAlias",
|
|
508
|
+
"type": { "dataType": "intersection", "subSchemas": [{ "ref": "Omit_CreateVifParams_91_0_93_.network-or-VM_" }, { "dataType": "union", "subSchemas": [{ "dataType": "nestedObjectLiteral", "nestedProperties": { "MAC": { "dataType": "string" } } }, { "dataType": "undefined" }] }, { "dataType": "nestedObjectLiteral", "nestedProperties": { "vmId": { "dataType": "string", "required": true }, "networkId": { "dataType": "string", "required": true } } }], "validators": {} },
|
|
509
|
+
},
|
|
510
|
+
// WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa
|
|
496
511
|
"Exclude_SUPPORTED_VDI_FORMAT.qcow2_": {
|
|
497
512
|
"dataType": "refAlias",
|
|
498
513
|
"type": { "dataType": "union", "subSchemas": [{ "dataType": "enum", "enums": ["raw"] }, { "dataType": "enum", "enums": ["vhd"] }], "validators": {} },
|
|
@@ -503,6 +518,11 @@ const models = {
|
|
|
503
518
|
"type": { "dataType": "nestedObjectLiteral", "nestedProperties": { "$pool": { "dataType": "string", "required": true }, "$poolId": { "dataType": "string", "required": true }, "_xapiRef": { "dataType": "string", "required": true }, "uuid": { "dataType": "string", "required": true }, "$SR": { "dataType": "string", "required": true }, "$VBDs": { "dataType": "array", "array": { "dataType": "string" }, "required": true }, "VDI_type": { "ref": "VDI_TYPE", "required": true }, "cbt_enabled": { "dataType": "union", "subSchemas": [{ "dataType": "boolean" }, { "dataType": "undefined" }] }, "current_operations": { "ref": "Record_string.VDI_OPERATIONS_", "required": true }, "missing": { "dataType": "boolean", "required": true }, "name_description": { "dataType": "string", "required": true }, "name_label": { "dataType": "string", "required": true }, "other_config": { "ref": "Record_string.string_", "required": true }, "parent": { "dataType": "union", "subSchemas": [{ "dataType": "string" }, { "dataType": "undefined" }] }, "image_format": { "dataType": "union", "subSchemas": [{ "dataType": "string" }, { "dataType": "undefined" }] }, "size": { "dataType": "double", "required": true }, "snapshots": { "dataType": "array", "array": { "dataType": "string" }, "required": true }, "tags": { "dataType": "array", "array": { "dataType": "string" }, "required": true }, "usage": { "dataType": "double", "required": true }, "id": { "dataType": "string", "required": true }, "type": { "dataType": "enum", "enums": ["VDI"], "required": true } }, "validators": {} },
|
|
504
519
|
},
|
|
505
520
|
// WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa
|
|
521
|
+
"CreateActionReturnType__id-Unbrand_XoVdi__91_id_93___": {
|
|
522
|
+
"dataType": "refAlias",
|
|
523
|
+
"type": { "dataType": "union", "subSchemas": [{ "dataType": "nestedObjectLiteral", "nestedProperties": { "taskId": { "dataType": "string", "required": true } } }, { "dataType": "nestedObjectLiteral", "nestedProperties": { "id": { "dataType": "string", "required": true } } }], "validators": {} },
|
|
524
|
+
},
|
|
525
|
+
// WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa
|
|
506
526
|
"Unbrand_XoVdiSnapshot_": {
|
|
507
527
|
"dataType": "refAlias",
|
|
508
528
|
"type": { "dataType": "nestedObjectLiteral", "nestedProperties": { "$pool": { "dataType": "string", "required": true }, "$poolId": { "dataType": "string", "required": true }, "_xapiRef": { "dataType": "string", "required": true }, "uuid": { "dataType": "string", "required": true }, "$SR": { "dataType": "string", "required": true }, "$VBDs": { "dataType": "array", "array": { "dataType": "string" }, "required": true }, "VDI_type": { "ref": "VDI_TYPE", "required": true }, "cbt_enabled": { "dataType": "union", "subSchemas": [{ "dataType": "boolean" }, { "dataType": "undefined" }] }, "current_operations": { "ref": "Record_string.VDI_OPERATIONS_", "required": true }, "missing": { "dataType": "boolean", "required": true }, "name_description": { "dataType": "string", "required": true }, "name_label": { "dataType": "string", "required": true }, "other_config": { "ref": "Record_string.string_", "required": true }, "parent": { "dataType": "union", "subSchemas": [{ "dataType": "string" }, { "dataType": "undefined" }] }, "image_format": { "dataType": "union", "subSchemas": [{ "dataType": "string" }, { "dataType": "undefined" }] }, "size": { "dataType": "double", "required": true }, "snapshots": { "dataType": "array", "array": { "dataType": "string" }, "required": true }, "tags": { "dataType": "array", "array": { "dataType": "string" }, "required": true }, "usage": { "dataType": "double", "required": true }, "id": { "dataType": "string", "required": true }, "snapshot_time": { "dataType": "double", "required": true }, "$snapshot_of": { "dataType": "union", "subSchemas": [{ "dataType": "string" }, { "dataType": "undefined" }] }, "type": { "dataType": "enum", "enums": ["VDI-snapshot"], "required": true } }, "validators": {} },
|
|
@@ -520,7 +540,7 @@ const models = {
|
|
|
520
540
|
// WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa
|
|
521
541
|
"Pick_Unbrand_Parameters_Xapi_91_VBD_create_93___91_0_93__.Exclude_keyofUnbrand_Parameters_Xapi_91_VBD_create_93___91_0_93__.VM-or-VDI__": {
|
|
522
542
|
"dataType": "refAlias",
|
|
523
|
-
"type": { "dataType": "nestedObjectLiteral", "nestedProperties": { "type": { "dataType": "union", "subSchemas": [{ "ref": "VBD_TYPE" }, { "dataType": "undefined" }] }, "other_config": { "dataType": "union", "subSchemas": [{ "ref": "Record_string.string_" }, { "dataType": "undefined" }] }, "mode": { "dataType": "union", "subSchemas": [{ "ref": "VBD_MODE" }, { "dataType": "undefined" }] }, "
|
|
543
|
+
"type": { "dataType": "nestedObjectLiteral", "nestedProperties": { "type": { "dataType": "union", "subSchemas": [{ "ref": "VBD_TYPE" }, { "dataType": "undefined" }] }, "other_config": { "dataType": "union", "subSchemas": [{ "ref": "Record_string.string_" }, { "dataType": "undefined" }] }, "mode": { "dataType": "union", "subSchemas": [{ "ref": "VBD_MODE" }, { "dataType": "undefined" }] }, "qos_algorithm_params": { "dataType": "union", "subSchemas": [{ "ref": "Record_string.string_" }, { "dataType": "undefined" }] }, "qos_algorithm_type": { "dataType": "union", "subSchemas": [{ "dataType": "string" }, { "dataType": "undefined" }] }, "bootable": { "dataType": "union", "subSchemas": [{ "dataType": "boolean" }, { "dataType": "undefined" }] }, "empty": { "dataType": "union", "subSchemas": [{ "dataType": "boolean" }, { "dataType": "undefined" }] }, "unpluggable": { "dataType": "union", "subSchemas": [{ "dataType": "boolean" }, { "dataType": "undefined" }] }, "userdevice": { "dataType": "union", "subSchemas": [{ "dataType": "string" }, { "dataType": "undefined" }] } }, "validators": {} },
|
|
524
544
|
},
|
|
525
545
|
// WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa
|
|
526
546
|
"Omit_Unbrand_Parameters_Xapi_91_VBD_create_93___91_0_93__.VM-or-VDI_": {
|
|
@@ -802,7 +822,7 @@ const models = {
|
|
|
802
822
|
// WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa
|
|
803
823
|
"Unbrand_CreateVmBody_": {
|
|
804
824
|
"dataType": "refAlias",
|
|
805
|
-
"type": { "dataType": "nestedObjectLiteral", "nestedProperties": { "memory": { "dataType": "union", "subSchemas": [{ "dataType": "double" }, { "dataType": "undefined" }] }, "name_description": { "dataType": "union", "subSchemas": [{ "dataType": "string" }, { "dataType": "undefined" }] }, "name_label": { "dataType": "string", "required": true }, "secureBoot": { "dataType": "union", "subSchemas": [{ "dataType": "boolean" }, { "dataType": "undefined" }] }, "clone": { "dataType": "union", "subSchemas": [{ "dataType": "boolean" }, { "dataType": "undefined" }] }, "gpuGroup": { "dataType": "union", "subSchemas": [{ "dataType": "string" }, { "dataType": "undefined" }] }, "vgpuType": { "dataType": "union", "subSchemas": [{ "dataType": "string" }, { "dataType": "undefined" }] }, "autoPoweron": { "dataType": "union", "subSchemas": [{ "dataType": "boolean" }, { "dataType": "undefined" }] }, "vifs": { "dataType": "union", "subSchemas": [{ "dataType": "array", "array": { "dataType": "union", "subSchemas": [{ "dataType": "nestedObjectLiteral", "nestedProperties": { "network": { "dataType": "string", "required": true }, "mtu": { "dataType": "union", "subSchemas": [{ "dataType": "double" }, { "dataType": "undefined" }] }, "mac": { "dataType": "union", "subSchemas": [{ "dataType": "string" }, { "dataType": "undefined" }] }, "ipv6_allowed": { "dataType": "union", "subSchemas": [{ "dataType": "array", "array": { "dataType": "string" } }, { "dataType": "undefined" }] }, "ipv4_allowed": { "dataType": "union", "subSchemas": [{ "dataType": "array", "array": { "dataType": "string" } }, { "dataType": "undefined" }] }, "device": { "dataType": "union", "subSchemas": [{ "dataType": "string" }, { "dataType": "undefined" }] } } }, { "dataType": "nestedObjectLiteral", "nestedProperties": { "device": { "dataType": "string", "required": true }, "destroy": { "dataType": "enum", "enums": [true], "required": true } } }] } }, { "dataType": "undefined" }] }, "copyHostBiosStrings": { "dataType": "union", "subSchemas": [{ "dataType": "boolean" }, { "dataType": "undefined" }] }, "hvmBootFirmware": { "dataType": "union", "subSchemas": [{ "dataType": "enum", "enums": ["uefi"] }, { "dataType": "enum", "enums": ["bios"] }, { "dataType": "undefined" }] }, "template": { "dataType": "string", "required": true }, "affinity": { "dataType": "union", "subSchemas": [{ "dataType": "string" }, { "dataType": "undefined" }] }, "vdis": { "dataType": "union", "subSchemas": [{ "dataType": "array", "array": { "dataType": "union", "subSchemas": [{ "dataType": "nestedObjectLiteral", "nestedProperties": { "name_description": { "dataType": "union", "subSchemas": [{ "dataType": "string" }, { "dataType": "undefined" }] }, "sr": { "dataType": "union", "subSchemas": [{ "dataType": "string" }, { "dataType": "undefined" }] }, "size": { "dataType": "double", "required": true }, "name_label": { "dataType": "string", "required": true } } }, { "dataType": "nestedObjectLiteral", "nestedProperties": { "name_description": { "dataType": "union", "subSchemas": [{ "dataType": "string" }, { "dataType": "undefined" }] }, "sr": { "dataType": "union", "subSchemas": [{ "dataType": "string" }, { "dataType": "undefined" }] }, "size": { "dataType": "union", "subSchemas": [{ "dataType": "double" }, { "dataType": "undefined" }] }, "name_label": { "dataType": "union", "subSchemas": [{ "dataType": "string" }, { "dataType": "undefined" }] }, "userdevice": { "dataType": "string", "required": true } } }, { "dataType": "nestedObjectLiteral", "nestedProperties": { "userdervice": { "dataType": "string", "required": true }, "destroy": { "dataType": "enum", "enums": [true], "required": true } } }] } }, { "dataType": "undefined" }] }, "install": { "dataType": "union", "subSchemas": [{ "dataType": "nestedObjectLiteral", "nestedProperties": { "repository": { "dataType": "string", "required": true }, "method": { "dataType": "
|
|
825
|
+
"type": { "dataType": "nestedObjectLiteral", "nestedProperties": { "memory": { "dataType": "union", "subSchemas": [{ "dataType": "double" }, { "dataType": "undefined" }] }, "name_description": { "dataType": "union", "subSchemas": [{ "dataType": "string" }, { "dataType": "undefined" }] }, "name_label": { "dataType": "string", "required": true }, "secureBoot": { "dataType": "union", "subSchemas": [{ "dataType": "boolean" }, { "dataType": "undefined" }] }, "clone": { "dataType": "union", "subSchemas": [{ "dataType": "boolean" }, { "dataType": "undefined" }] }, "gpuGroup": { "dataType": "union", "subSchemas": [{ "dataType": "string" }, { "dataType": "undefined" }] }, "vgpuType": { "dataType": "union", "subSchemas": [{ "dataType": "string" }, { "dataType": "undefined" }] }, "autoPoweron": { "dataType": "union", "subSchemas": [{ "dataType": "boolean" }, { "dataType": "undefined" }] }, "vifs": { "dataType": "union", "subSchemas": [{ "dataType": "array", "array": { "dataType": "union", "subSchemas": [{ "dataType": "nestedObjectLiteral", "nestedProperties": { "network": { "dataType": "string", "required": true }, "mtu": { "dataType": "union", "subSchemas": [{ "dataType": "double" }, { "dataType": "undefined" }] }, "mac": { "dataType": "union", "subSchemas": [{ "dataType": "string" }, { "dataType": "undefined" }] }, "ipv6_allowed": { "dataType": "union", "subSchemas": [{ "dataType": "array", "array": { "dataType": "string" } }, { "dataType": "undefined" }] }, "ipv4_allowed": { "dataType": "union", "subSchemas": [{ "dataType": "array", "array": { "dataType": "string" } }, { "dataType": "undefined" }] }, "device": { "dataType": "union", "subSchemas": [{ "dataType": "string" }, { "dataType": "undefined" }] } } }, { "dataType": "nestedObjectLiteral", "nestedProperties": { "device": { "dataType": "string", "required": true }, "destroy": { "dataType": "enum", "enums": [true], "required": true } } }] } }, { "dataType": "undefined" }] }, "copyHostBiosStrings": { "dataType": "union", "subSchemas": [{ "dataType": "boolean" }, { "dataType": "undefined" }] }, "hvmBootFirmware": { "dataType": "union", "subSchemas": [{ "dataType": "enum", "enums": ["uefi"] }, { "dataType": "enum", "enums": ["bios"] }, { "dataType": "undefined" }] }, "template": { "dataType": "string", "required": true }, "affinity": { "dataType": "union", "subSchemas": [{ "dataType": "string" }, { "dataType": "undefined" }] }, "vdis": { "dataType": "union", "subSchemas": [{ "dataType": "array", "array": { "dataType": "union", "subSchemas": [{ "dataType": "nestedObjectLiteral", "nestedProperties": { "name_description": { "dataType": "union", "subSchemas": [{ "dataType": "string" }, { "dataType": "undefined" }] }, "sr": { "dataType": "union", "subSchemas": [{ "dataType": "string" }, { "dataType": "undefined" }] }, "size": { "dataType": "double", "required": true }, "name_label": { "dataType": "string", "required": true } } }, { "dataType": "nestedObjectLiteral", "nestedProperties": { "name_description": { "dataType": "union", "subSchemas": [{ "dataType": "string" }, { "dataType": "undefined" }] }, "sr": { "dataType": "union", "subSchemas": [{ "dataType": "string" }, { "dataType": "undefined" }] }, "size": { "dataType": "union", "subSchemas": [{ "dataType": "double" }, { "dataType": "undefined" }] }, "name_label": { "dataType": "union", "subSchemas": [{ "dataType": "string" }, { "dataType": "undefined" }] }, "userdevice": { "dataType": "string", "required": true } } }, { "dataType": "nestedObjectLiteral", "nestedProperties": { "userdervice": { "dataType": "string", "required": true }, "destroy": { "dataType": "enum", "enums": [true], "required": true } } }] } }, { "dataType": "undefined" }] }, "install": { "dataType": "union", "subSchemas": [{ "dataType": "nestedObjectLiteral", "nestedProperties": { "repository": { "dataType": "string", "required": true }, "method": { "dataType": "enum", "enums": ["cdrom"], "required": true } } }, { "dataType": "nestedObjectLiteral", "nestedProperties": { "repository": { "dataType": "enum", "enums": [""], "required": true }, "method": { "dataType": "enum", "enums": ["network"], "required": true } } }, { "dataType": "undefined" }] }, "cloud_config": { "dataType": "union", "subSchemas": [{ "dataType": "string" }, { "dataType": "undefined" }] }, "network_config": { "dataType": "union", "subSchemas": [{ "dataType": "string" }, { "dataType": "undefined" }] }, "boot": { "dataType": "union", "subSchemas": [{ "dataType": "boolean" }, { "dataType": "undefined" }] }, "destroy_cloud_config_vdi": { "dataType": "union", "subSchemas": [{ "dataType": "boolean" }, { "dataType": "undefined" }] }, "createVtpm": { "dataType": "union", "subSchemas": [{ "dataType": "boolean" }, { "dataType": "undefined" }] } }, "validators": {} },
|
|
806
826
|
},
|
|
807
827
|
// WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa
|
|
808
828
|
"XapiHostStatsRaw": {
|
|
@@ -3049,6 +3069,60 @@ export function RegisterRoutes(app) {
|
|
|
3049
3069
|
}
|
|
3050
3070
|
});
|
|
3051
3071
|
// WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa
|
|
3072
|
+
const argsVifController_createVif = {
|
|
3073
|
+
body: { "in": "body", "name": "body", "required": true, "ref": "CreateVifBody" },
|
|
3074
|
+
};
|
|
3075
|
+
app.post('/rest/v0/vifs', authenticateMiddleware([{ "*": [] }]), ...(fetchMiddlewares(VifController)), ...(fetchMiddlewares(VifController.prototype.createVif)), async function VifController_createVif(request, response, next) {
|
|
3076
|
+
// WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa
|
|
3077
|
+
let validatedArgs = [];
|
|
3078
|
+
try {
|
|
3079
|
+
validatedArgs = templateService.getValidatedArgs({ args: argsVifController_createVif, request, response });
|
|
3080
|
+
const container = typeof iocContainer === 'function' ? iocContainer(request) : iocContainer;
|
|
3081
|
+
const controller = await container.get(VifController);
|
|
3082
|
+
if (typeof controller['setStatus'] === 'function') {
|
|
3083
|
+
controller.setStatus(undefined);
|
|
3084
|
+
}
|
|
3085
|
+
await templateService.apiHandler({
|
|
3086
|
+
methodName: 'createVif',
|
|
3087
|
+
controller,
|
|
3088
|
+
response,
|
|
3089
|
+
next,
|
|
3090
|
+
validatedArgs,
|
|
3091
|
+
successStatus: 201,
|
|
3092
|
+
});
|
|
3093
|
+
}
|
|
3094
|
+
catch (err) {
|
|
3095
|
+
return next(err);
|
|
3096
|
+
}
|
|
3097
|
+
});
|
|
3098
|
+
// WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa
|
|
3099
|
+
const argsVifController_destroyVif = {
|
|
3100
|
+
id: { "in": "path", "name": "id", "required": true, "dataType": "string" },
|
|
3101
|
+
};
|
|
3102
|
+
app.delete('/rest/v0/vifs/:id', authenticateMiddleware([{ "*": [] }]), ...(fetchMiddlewares(VifController)), ...(fetchMiddlewares(VifController.prototype.destroyVif)), async function VifController_destroyVif(request, response, next) {
|
|
3103
|
+
// WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa
|
|
3104
|
+
let validatedArgs = [];
|
|
3105
|
+
try {
|
|
3106
|
+
validatedArgs = templateService.getValidatedArgs({ args: argsVifController_destroyVif, request, response });
|
|
3107
|
+
const container = typeof iocContainer === 'function' ? iocContainer(request) : iocContainer;
|
|
3108
|
+
const controller = await container.get(VifController);
|
|
3109
|
+
if (typeof controller['setStatus'] === 'function') {
|
|
3110
|
+
controller.setStatus(undefined);
|
|
3111
|
+
}
|
|
3112
|
+
await templateService.apiHandler({
|
|
3113
|
+
methodName: 'destroyVif',
|
|
3114
|
+
controller,
|
|
3115
|
+
response,
|
|
3116
|
+
next,
|
|
3117
|
+
validatedArgs,
|
|
3118
|
+
successStatus: 204,
|
|
3119
|
+
});
|
|
3120
|
+
}
|
|
3121
|
+
catch (err) {
|
|
3122
|
+
return next(err);
|
|
3123
|
+
}
|
|
3124
|
+
});
|
|
3125
|
+
// WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa
|
|
3052
3126
|
const argsVdiController_getVdis = {
|
|
3053
3127
|
req: { "in": "request", "name": "req", "required": true, "dataType": "object" },
|
|
3054
3128
|
fields: { "in": "query", "name": "fields", "dataType": "string" },
|
|
@@ -3288,6 +3362,35 @@ export function RegisterRoutes(app) {
|
|
|
3288
3362
|
}
|
|
3289
3363
|
});
|
|
3290
3364
|
// WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa
|
|
3365
|
+
const argsVdiController_migrateVdi = {
|
|
3366
|
+
id: { "in": "path", "name": "id", "required": true, "dataType": "string" },
|
|
3367
|
+
body: { "in": "body", "name": "body", "required": true, "dataType": "nestedObjectLiteral", "nestedProperties": { "srId": { "dataType": "string", "required": true } } },
|
|
3368
|
+
sync: { "in": "query", "name": "sync", "dataType": "boolean" },
|
|
3369
|
+
};
|
|
3370
|
+
app.post('/rest/v0/vdis/:id/actions/migrate', authenticateMiddleware([{ "*": [] }]), ...(fetchMiddlewares(VdiController)), ...(fetchMiddlewares(VdiController.prototype.migrateVdi)), async function VdiController_migrateVdi(request, response, next) {
|
|
3371
|
+
// WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa
|
|
3372
|
+
let validatedArgs = [];
|
|
3373
|
+
try {
|
|
3374
|
+
validatedArgs = templateService.getValidatedArgs({ args: argsVdiController_migrateVdi, request, response });
|
|
3375
|
+
const container = typeof iocContainer === 'function' ? iocContainer(request) : iocContainer;
|
|
3376
|
+
const controller = await container.get(VdiController);
|
|
3377
|
+
if (typeof controller['setStatus'] === 'function') {
|
|
3378
|
+
controller.setStatus(undefined);
|
|
3379
|
+
}
|
|
3380
|
+
await templateService.apiHandler({
|
|
3381
|
+
methodName: 'migrateVdi',
|
|
3382
|
+
controller,
|
|
3383
|
+
response,
|
|
3384
|
+
next,
|
|
3385
|
+
validatedArgs,
|
|
3386
|
+
successStatus: 202,
|
|
3387
|
+
});
|
|
3388
|
+
}
|
|
3389
|
+
catch (err) {
|
|
3390
|
+
return next(err);
|
|
3391
|
+
}
|
|
3392
|
+
});
|
|
3393
|
+
// WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa
|
|
3291
3394
|
const argsVdiController_putVdiTag = {
|
|
3292
3395
|
id: { "in": "path", "name": "id", "required": true, "dataType": "string" },
|
|
3293
3396
|
tag: { "in": "path", "name": "tag", "required": true, "dataType": "string" },
|
|
@@ -3818,6 +3921,62 @@ export function RegisterRoutes(app) {
|
|
|
3818
3921
|
}
|
|
3819
3922
|
});
|
|
3820
3923
|
// WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa
|
|
3924
|
+
const argsVbdController_connectVbd = {
|
|
3925
|
+
id: { "in": "path", "name": "id", "required": true, "dataType": "string" },
|
|
3926
|
+
sync: { "in": "query", "name": "sync", "dataType": "boolean" },
|
|
3927
|
+
};
|
|
3928
|
+
app.post('/rest/v0/vbds/:id/actions/connect', authenticateMiddleware([{ "*": [] }]), ...(fetchMiddlewares(VbdController)), ...(fetchMiddlewares(VbdController.prototype.connectVbd)), async function VbdController_connectVbd(request, response, next) {
|
|
3929
|
+
// WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa
|
|
3930
|
+
let validatedArgs = [];
|
|
3931
|
+
try {
|
|
3932
|
+
validatedArgs = templateService.getValidatedArgs({ args: argsVbdController_connectVbd, request, response });
|
|
3933
|
+
const container = typeof iocContainer === 'function' ? iocContainer(request) : iocContainer;
|
|
3934
|
+
const controller = await container.get(VbdController);
|
|
3935
|
+
if (typeof controller['setStatus'] === 'function') {
|
|
3936
|
+
controller.setStatus(undefined);
|
|
3937
|
+
}
|
|
3938
|
+
await templateService.apiHandler({
|
|
3939
|
+
methodName: 'connectVbd',
|
|
3940
|
+
controller,
|
|
3941
|
+
response,
|
|
3942
|
+
next,
|
|
3943
|
+
validatedArgs,
|
|
3944
|
+
successStatus: 202,
|
|
3945
|
+
});
|
|
3946
|
+
}
|
|
3947
|
+
catch (err) {
|
|
3948
|
+
return next(err);
|
|
3949
|
+
}
|
|
3950
|
+
});
|
|
3951
|
+
// WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa
|
|
3952
|
+
const argsVbdController_disconnectVbd = {
|
|
3953
|
+
id: { "in": "path", "name": "id", "required": true, "dataType": "string" },
|
|
3954
|
+
sync: { "in": "query", "name": "sync", "dataType": "boolean" },
|
|
3955
|
+
};
|
|
3956
|
+
app.post('/rest/v0/vbds/:id/actions/disconnect', authenticateMiddleware([{ "*": [] }]), ...(fetchMiddlewares(VbdController)), ...(fetchMiddlewares(VbdController.prototype.disconnectVbd)), async function VbdController_disconnectVbd(request, response, next) {
|
|
3957
|
+
// WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa
|
|
3958
|
+
let validatedArgs = [];
|
|
3959
|
+
try {
|
|
3960
|
+
validatedArgs = templateService.getValidatedArgs({ args: argsVbdController_disconnectVbd, request, response });
|
|
3961
|
+
const container = typeof iocContainer === 'function' ? iocContainer(request) : iocContainer;
|
|
3962
|
+
const controller = await container.get(VbdController);
|
|
3963
|
+
if (typeof controller['setStatus'] === 'function') {
|
|
3964
|
+
controller.setStatus(undefined);
|
|
3965
|
+
}
|
|
3966
|
+
await templateService.apiHandler({
|
|
3967
|
+
methodName: 'disconnectVbd',
|
|
3968
|
+
controller,
|
|
3969
|
+
response,
|
|
3970
|
+
next,
|
|
3971
|
+
validatedArgs,
|
|
3972
|
+
successStatus: 202,
|
|
3973
|
+
});
|
|
3974
|
+
}
|
|
3975
|
+
catch (err) {
|
|
3976
|
+
return next(err);
|
|
3977
|
+
}
|
|
3978
|
+
});
|
|
3979
|
+
// WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa
|
|
3821
3980
|
const argsUserController_getUsers = {
|
|
3822
3981
|
req: { "in": "request", "name": "req", "required": true, "dataType": "object" },
|
|
3823
3982
|
fields: { "in": "query", "name": "fields", "dataType": "string" },
|
|
@@ -166,9 +166,18 @@ let PoolController = class PoolController extends XapiXoController {
|
|
|
166
166
|
async createVm(id, body, sync) {
|
|
167
167
|
const poolId = id;
|
|
168
168
|
const action = async () => {
|
|
169
|
-
const { affinity, template, ...rest } = body;
|
|
170
|
-
|
|
171
|
-
const vmId = await this.#vmService.create({
|
|
169
|
+
const { affinity, template, install, vgpuType, gpuGroup, vdis, ...rest } = body;
|
|
170
|
+
// rebrand all branded type
|
|
171
|
+
const vmId = await this.#vmService.create({
|
|
172
|
+
affinityHost: affinity,
|
|
173
|
+
installRepository: install?.repository,
|
|
174
|
+
pool: poolId,
|
|
175
|
+
template: template,
|
|
176
|
+
vdis: vdis,
|
|
177
|
+
vgpuType: vgpuType,
|
|
178
|
+
gpuGroup: gpuGroup,
|
|
179
|
+
...rest,
|
|
180
|
+
});
|
|
172
181
|
return { id: vmId };
|
|
173
182
|
};
|
|
174
183
|
return this.createAction(action, {
|
|
@@ -163,7 +163,7 @@ export class PoolService {
|
|
|
163
163
|
#getCpuProvisioning(poolId) {
|
|
164
164
|
const pool = this.#restApi.getObject(poolId, 'pool');
|
|
165
165
|
const vms = this.#restApi.getObjectsByType('VM', {
|
|
166
|
-
filter: vm => vm.$pool === poolId,
|
|
166
|
+
filter: vm => vm.$pool === poolId && vm.power_state === VM_POWER_STATE.RUNNING,
|
|
167
167
|
});
|
|
168
168
|
let assignedVcpu = 0;
|
|
169
169
|
for (const id in vms) {
|
|
@@ -15,13 +15,13 @@ import { provide } from 'inversify-binding-decorators';
|
|
|
15
15
|
import { AlarmService } from '../alarms/alarm.service.mjs';
|
|
16
16
|
import { escapeUnsafeComplexMatcher } from '../helpers/utils.helper.mjs';
|
|
17
17
|
import { genericAlarmsExample } from '../open-api/oa-examples/alarm.oa-example.mjs';
|
|
18
|
-
import { badRequestResp, createdResp, invalidParameters, noContentResp, notFoundResp, unauthorizedResp, } from '../open-api/common/response.common.mjs';
|
|
18
|
+
import { asynchronousActionResp, badRequestResp, createdResp, internalServerErrorResp, invalidParameters, noContentResp, notFoundResp, unauthorizedResp, } from '../open-api/common/response.common.mjs';
|
|
19
19
|
import { BASE_URL } from '../index.mjs';
|
|
20
20
|
import { partialVbds, vbd, vbdId, vbdIds } from '../open-api/oa-examples/vbd.oa-example.mjs';
|
|
21
21
|
import { RestApi } from '../rest-api/rest-api.mjs';
|
|
22
22
|
import { XapiXoController } from '../abstract-classes/xapi-xo-controller.mjs';
|
|
23
23
|
import { messageIds, partialMessages } from '../open-api/oa-examples/message.oa-example.mjs';
|
|
24
|
-
import { taskIds, partialTasks } from '../open-api/oa-examples/task.oa-example.mjs';
|
|
24
|
+
import { taskIds, taskLocation, partialTasks } from '../open-api/oa-examples/task.oa-example.mjs';
|
|
25
25
|
let VbdController = class VbdController extends XapiXoController {
|
|
26
26
|
#alarmService;
|
|
27
27
|
constructor(restApi, alarmService) {
|
|
@@ -113,6 +113,44 @@ let VbdController = class VbdController extends XapiXoController {
|
|
|
113
113
|
const tasks = await this.getTasksForObject(id, { filter, limit });
|
|
114
114
|
return this.sendObjects(Object.values(tasks), req, 'tasks');
|
|
115
115
|
}
|
|
116
|
+
/**
|
|
117
|
+
* Hotplug the VBD, dynamically attaching it to the running VM
|
|
118
|
+
* @example id "f07ab729-c0e8-721c-45ec-f11276377030"
|
|
119
|
+
*/
|
|
120
|
+
connectVbd(id, sync) {
|
|
121
|
+
const vbdId = id;
|
|
122
|
+
const action = async () => {
|
|
123
|
+
const xapiVbd = this.getXapiObject(vbdId);
|
|
124
|
+
await xapiVbd.$xapi.callAsync('VBD.plug', xapiVbd.$ref);
|
|
125
|
+
};
|
|
126
|
+
return this.createAction(action, {
|
|
127
|
+
sync,
|
|
128
|
+
statusCode: noContentResp.status,
|
|
129
|
+
taskProperties: {
|
|
130
|
+
name: 'connect VBD',
|
|
131
|
+
objectId: vbdId,
|
|
132
|
+
},
|
|
133
|
+
});
|
|
134
|
+
}
|
|
135
|
+
/**
|
|
136
|
+
* Hot-unplug the VBD, dynamically detaching it from the running VM
|
|
137
|
+
* @example id "f07ab729-c0e8-721c-45ec-f11276377030"
|
|
138
|
+
*/
|
|
139
|
+
disconnectVbd(id, sync) {
|
|
140
|
+
const vbdId = id;
|
|
141
|
+
const action = async () => {
|
|
142
|
+
const xapiVbd = this.getXapiObject(vbdId);
|
|
143
|
+
await xapiVbd.$xapi.VBD_unplug(xapiVbd.$ref);
|
|
144
|
+
};
|
|
145
|
+
return this.createAction(action, {
|
|
146
|
+
sync,
|
|
147
|
+
statusCode: noContentResp.status,
|
|
148
|
+
taskProperties: {
|
|
149
|
+
name: 'disconnect VBD',
|
|
150
|
+
objectId: vbdId,
|
|
151
|
+
},
|
|
152
|
+
});
|
|
153
|
+
}
|
|
116
154
|
};
|
|
117
155
|
__decorate([
|
|
118
156
|
Example(vbdId),
|
|
@@ -183,6 +221,26 @@ __decorate([
|
|
|
183
221
|
__param(4, Query()),
|
|
184
222
|
__param(5, Query())
|
|
185
223
|
], VbdController.prototype, "getVbdTasks", null);
|
|
224
|
+
__decorate([
|
|
225
|
+
Example(taskLocation),
|
|
226
|
+
Post('{id}/actions/connect'),
|
|
227
|
+
SuccessResponse(asynchronousActionResp.status, asynchronousActionResp.description),
|
|
228
|
+
Response(noContentResp.status, noContentResp.description),
|
|
229
|
+
Response(notFoundResp.status, notFoundResp.description),
|
|
230
|
+
Response(internalServerErrorResp.status, internalServerErrorResp.description),
|
|
231
|
+
__param(0, Path()),
|
|
232
|
+
__param(1, Query())
|
|
233
|
+
], VbdController.prototype, "connectVbd", null);
|
|
234
|
+
__decorate([
|
|
235
|
+
Example(taskLocation),
|
|
236
|
+
Post('{id}/actions/disconnect'),
|
|
237
|
+
SuccessResponse(asynchronousActionResp.status, asynchronousActionResp.description),
|
|
238
|
+
Response(noContentResp.status, noContentResp.description),
|
|
239
|
+
Response(notFoundResp.status, notFoundResp.description),
|
|
240
|
+
Response(internalServerErrorResp.status, internalServerErrorResp.description),
|
|
241
|
+
__param(0, Path()),
|
|
242
|
+
__param(1, Query())
|
|
243
|
+
], VbdController.prototype, "disconnectVbd", null);
|
|
186
244
|
VbdController = __decorate([
|
|
187
245
|
Route('vbds'),
|
|
188
246
|
Security('*'),
|
|
@@ -7,19 +7,20 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
|
|
|
7
7
|
var __param = (this && this.__param) || function (paramIndex, decorator) {
|
|
8
8
|
return function (target, key) { decorator(target, key, paramIndex); }
|
|
9
9
|
};
|
|
10
|
-
import { Delete, Example, Get, Path, Put, Query, Request, Response, Route, Security, SuccessResponse, Tags } from 'tsoa';
|
|
10
|
+
import { Body, Delete, Example, Get, Middlewares, Path, Post, Put, Query, Request, Response, Route, Security, SuccessResponse, Tags, } from 'tsoa';
|
|
11
11
|
import { inject } from 'inversify';
|
|
12
12
|
import { provide } from 'inversify-binding-decorators';
|
|
13
|
+
import { json } from 'express';
|
|
13
14
|
import { AlarmService } from '../alarms/alarm.service.mjs';
|
|
14
15
|
import { escapeUnsafeComplexMatcher } from '../helpers/utils.helper.mjs';
|
|
15
16
|
import { genericAlarmsExample } from '../open-api/oa-examples/alarm.oa-example.mjs';
|
|
16
|
-
import { badRequestResp, internalServerErrorResp, noContentResp, notFoundResp, unauthorizedResp, } from '../open-api/common/response.common.mjs';
|
|
17
|
+
import { asynchronousActionResp, badRequestResp, internalServerErrorResp, noContentResp, notFoundResp, unauthorizedResp, } from '../open-api/common/response.common.mjs';
|
|
17
18
|
import { RestApi } from '../rest-api/rest-api.mjs';
|
|
18
19
|
import { XapiXoController } from '../abstract-classes/xapi-xo-controller.mjs';
|
|
19
|
-
import { partialVdis, vdi, vdiIds } from '../open-api/oa-examples/vdi.oa-example.mjs';
|
|
20
|
+
import { partialVdis, vdi, vdiId, vdiIds } from '../open-api/oa-examples/vdi.oa-example.mjs';
|
|
20
21
|
import { VdiService } from './vdi.service.mjs';
|
|
21
22
|
import { messageIds, partialMessages } from '../open-api/oa-examples/message.oa-example.mjs';
|
|
22
|
-
import { taskIds, partialTasks } from '../open-api/oa-examples/task.oa-example.mjs';
|
|
23
|
+
import { taskIds, partialTasks, taskLocation } from '../open-api/oa-examples/task.oa-example.mjs';
|
|
23
24
|
let VdiController = class VdiController extends XapiXoController {
|
|
24
25
|
#alarmService;
|
|
25
26
|
#vdiService;
|
|
@@ -110,6 +111,27 @@ let VdiController = class VdiController extends XapiXoController {
|
|
|
110
111
|
const tasks = await this.getTasksForObject(id, { filter, limit });
|
|
111
112
|
return this.sendObjects(Object.values(tasks), req, 'tasks');
|
|
112
113
|
}
|
|
114
|
+
/**
|
|
115
|
+
* Migrate a VDI to another SR.
|
|
116
|
+
*
|
|
117
|
+
* Note: After migration, the VDI will have a new ID. The new ID is returned in the response.
|
|
118
|
+
*
|
|
119
|
+
* @example id "c77f9955-c1d2-4b39-aa1c-73cdb2dacb7e"
|
|
120
|
+
* @example body { "srId": "4cb0d74e-a7c1-0b7d-46e3-09382c012abb" }
|
|
121
|
+
*/
|
|
122
|
+
async migrateVdi(id, body, sync) {
|
|
123
|
+
const vdiId = id;
|
|
124
|
+
return this.createAction(async () => {
|
|
125
|
+
const newVdi = await this.getXapi(vdiId).moveVdi(vdiId, body.srId);
|
|
126
|
+
return { id: newVdi.uuid };
|
|
127
|
+
}, {
|
|
128
|
+
sync,
|
|
129
|
+
taskProperties: {
|
|
130
|
+
name: 'migrate VDI',
|
|
131
|
+
objectId: vdiId,
|
|
132
|
+
},
|
|
133
|
+
});
|
|
134
|
+
}
|
|
113
135
|
/**
|
|
114
136
|
* @example id "c77f9955-c1d2-4b39-aa1c-73cdb2dacb7e"
|
|
115
137
|
* @example tag "from-rest-api"
|
|
@@ -206,6 +228,19 @@ __decorate([
|
|
|
206
228
|
__param(4, Query()),
|
|
207
229
|
__param(5, Query())
|
|
208
230
|
], VdiController.prototype, "getVdiTasks", null);
|
|
231
|
+
__decorate([
|
|
232
|
+
Example(taskLocation),
|
|
233
|
+
Example(vdiId),
|
|
234
|
+
Post('{id}/actions/migrate'),
|
|
235
|
+
Middlewares(json()),
|
|
236
|
+
SuccessResponse(asynchronousActionResp.status, asynchronousActionResp.description),
|
|
237
|
+
Response(200, 'Ok'),
|
|
238
|
+
Response(notFoundResp.status, notFoundResp.description),
|
|
239
|
+
Response(internalServerErrorResp.status, internalServerErrorResp.description),
|
|
240
|
+
__param(0, Path()),
|
|
241
|
+
__param(1, Body()),
|
|
242
|
+
__param(2, Query())
|
|
243
|
+
], VdiController.prototype, "migrateVdi", null);
|
|
209
244
|
__decorate([
|
|
210
245
|
Put('{id}/tags/{tag}'),
|
|
211
246
|
SuccessResponse(noContentResp.status, noContentResp.description),
|
|
@@ -7,14 +7,16 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
|
|
|
7
7
|
var __param = (this && this.__param) || function (paramIndex, decorator) {
|
|
8
8
|
return function (target, key) { decorator(target, key, paramIndex); }
|
|
9
9
|
};
|
|
10
|
-
import { Example, Get, Path, Query, Request, Response, Route, Security, Tags } from 'tsoa';
|
|
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
|
+
import { json } from 'express';
|
|
12
13
|
import { escapeUnsafeComplexMatcher } from '../helpers/utils.helper.mjs';
|
|
13
14
|
import { provide } from 'inversify-binding-decorators';
|
|
14
15
|
import { RestApi } from '../rest-api/rest-api.mjs';
|
|
15
|
-
import { badRequestResp, notFoundResp, unauthorizedResp } from '../open-api/common/response.common.mjs';
|
|
16
|
+
import { badRequestResp, createdResp, internalServerErrorResp, invalidParameters as invalidParametersResp, noContentResp, notFoundResp, unauthorizedResp, } from '../open-api/common/response.common.mjs';
|
|
17
|
+
import { invalidParameters } from 'xo-common/api-errors.js';
|
|
16
18
|
import { XapiXoController } from '../abstract-classes/xapi-xo-controller.mjs';
|
|
17
|
-
import { partialVifs, vif, vifIds } from '../open-api/oa-examples/vif.oa-example.mjs';
|
|
19
|
+
import { partialVifs, vif, vifId, vifIds } from '../open-api/oa-examples/vif.oa-example.mjs';
|
|
18
20
|
import { genericAlarmsExample } from '../open-api/oa-examples/alarm.oa-example.mjs';
|
|
19
21
|
import { AlarmService } from '../alarms/alarm.service.mjs';
|
|
20
22
|
import { messageIds, partialMessages } from '../open-api/oa-examples/message.oa-example.mjs';
|
|
@@ -73,6 +75,37 @@ let VifController = class VifController extends XapiXoController {
|
|
|
73
75
|
const tasks = await this.getTasksForObject(id, { filter, limit });
|
|
74
76
|
return this.sendObjects(Object.values(tasks), req, 'tasks');
|
|
75
77
|
}
|
|
78
|
+
/**
|
|
79
|
+
* @example body {
|
|
80
|
+
* "networkId": "6b6ca0f5-6611-0636-4b0a-1fb1c1e96414",
|
|
81
|
+
* "vmId": "613f541c-4bed-fc77-7ca8-2db6b68f079c"
|
|
82
|
+
* }
|
|
83
|
+
*/
|
|
84
|
+
async createVif(body) {
|
|
85
|
+
const { MAC, vmId, networkId, ...rest } = body;
|
|
86
|
+
const vm = this.restApi.getObject(vmId, 'VM');
|
|
87
|
+
const network = this.restApi.getObject(networkId, 'network');
|
|
88
|
+
if (vm.$pool !== network.$pool) {
|
|
89
|
+
throw invalidParameters(`the VM ${vmId} and network ${networkId} do not belong to the same pool`);
|
|
90
|
+
}
|
|
91
|
+
const xapi = this.getXapi(vmId);
|
|
92
|
+
const vifRef = await xapi.VIF_create({
|
|
93
|
+
...rest,
|
|
94
|
+
VM: vm._xapiRef,
|
|
95
|
+
network: network._xapiRef,
|
|
96
|
+
}, {
|
|
97
|
+
MAC,
|
|
98
|
+
});
|
|
99
|
+
const xapiVif = await xapi.barrier(vifRef);
|
|
100
|
+
return { id: xapiVif.uuid };
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* @example id "6b6ca0f5-6611-0636-4b0a-1fb1c1e96414"
|
|
104
|
+
*/
|
|
105
|
+
async destroyVif(id) {
|
|
106
|
+
const xapi = this.getXapi(id);
|
|
107
|
+
await xapi.deleteVif(id);
|
|
108
|
+
}
|
|
76
109
|
};
|
|
77
110
|
__decorate([
|
|
78
111
|
Example(vifIds),
|
|
@@ -128,6 +161,23 @@ __decorate([
|
|
|
128
161
|
__param(4, Query()),
|
|
129
162
|
__param(5, Query())
|
|
130
163
|
], VifController.prototype, "getVifTasks", null);
|
|
164
|
+
__decorate([
|
|
165
|
+
Example(vifId),
|
|
166
|
+
Post(''),
|
|
167
|
+
Middlewares(json()),
|
|
168
|
+
SuccessResponse(createdResp.status, createdResp.description),
|
|
169
|
+
Response(notFoundResp.status, notFoundResp.description),
|
|
170
|
+
Response(internalServerErrorResp.status, internalServerErrorResp.description),
|
|
171
|
+
Response(invalidParametersResp.status, invalidParametersResp.description),
|
|
172
|
+
__param(0, Body())
|
|
173
|
+
], VifController.prototype, "createVif", null);
|
|
174
|
+
__decorate([
|
|
175
|
+
Delete('{id}'),
|
|
176
|
+
SuccessResponse(noContentResp.status, noContentResp.description),
|
|
177
|
+
Response(notFoundResp.status, notFoundResp.description),
|
|
178
|
+
Response(internalServerErrorResp.status, internalServerErrorResp.description),
|
|
179
|
+
__param(0, Path())
|
|
180
|
+
], VifController.prototype, "destroyVif", null);
|
|
131
181
|
VifController = __decorate([
|
|
132
182
|
Route('vifs'),
|
|
133
183
|
Security('*'),
|
|
@@ -5559,6 +5559,80 @@
|
|
|
5559
5559
|
"UnbrandedXoVif": {
|
|
5560
5560
|
"$ref": "#/components/schemas/Unbrand_XoVif_"
|
|
5561
5561
|
},
|
|
5562
|
+
"Pick_CreateVifParams_91_0_93_.Exclude_keyofCreateVifParams_91_0_93_.network-or-VM__": {
|
|
5563
|
+
"properties": {
|
|
5564
|
+
"other_config": {
|
|
5565
|
+
"$ref": "#/components/schemas/Record_string.string_"
|
|
5566
|
+
},
|
|
5567
|
+
"device": {
|
|
5568
|
+
"type": "string"
|
|
5569
|
+
},
|
|
5570
|
+
"MTU": {
|
|
5571
|
+
"type": "number",
|
|
5572
|
+
"format": "double"
|
|
5573
|
+
},
|
|
5574
|
+
"currently_attached": {
|
|
5575
|
+
"type": "boolean"
|
|
5576
|
+
},
|
|
5577
|
+
"ipv4_allowed": {
|
|
5578
|
+
"items": {
|
|
5579
|
+
"type": "string"
|
|
5580
|
+
},
|
|
5581
|
+
"type": "array"
|
|
5582
|
+
},
|
|
5583
|
+
"ipv6_allowed": {
|
|
5584
|
+
"items": {
|
|
5585
|
+
"type": "string"
|
|
5586
|
+
},
|
|
5587
|
+
"type": "array"
|
|
5588
|
+
},
|
|
5589
|
+
"locking_mode": {
|
|
5590
|
+
"$ref": "#/components/schemas/VIF_LOCKING_MODE"
|
|
5591
|
+
},
|
|
5592
|
+
"qos_algorithm_params": {
|
|
5593
|
+
"$ref": "#/components/schemas/Record_string.string_"
|
|
5594
|
+
},
|
|
5595
|
+
"qos_algorithm_type": {
|
|
5596
|
+
"type": "string"
|
|
5597
|
+
}
|
|
5598
|
+
},
|
|
5599
|
+
"type": "object",
|
|
5600
|
+
"description": "From T, pick a set of properties whose keys are in the union K"
|
|
5601
|
+
},
|
|
5602
|
+
"Omit_CreateVifParams_91_0_93_.network-or-VM_": {
|
|
5603
|
+
"$ref": "#/components/schemas/Pick_CreateVifParams_91_0_93_.Exclude_keyofCreateVifParams_91_0_93_.network-or-VM__",
|
|
5604
|
+
"description": "Construct a type with the properties of T except for those in type K."
|
|
5605
|
+
},
|
|
5606
|
+
"CreateVifBody": {
|
|
5607
|
+
"allOf": [
|
|
5608
|
+
{
|
|
5609
|
+
"$ref": "#/components/schemas/Omit_CreateVifParams_91_0_93_.network-or-VM_"
|
|
5610
|
+
},
|
|
5611
|
+
{
|
|
5612
|
+
"properties": {
|
|
5613
|
+
"MAC": {
|
|
5614
|
+
"type": "string"
|
|
5615
|
+
}
|
|
5616
|
+
},
|
|
5617
|
+
"type": "object"
|
|
5618
|
+
},
|
|
5619
|
+
{
|
|
5620
|
+
"properties": {
|
|
5621
|
+
"vmId": {
|
|
5622
|
+
"type": "string"
|
|
5623
|
+
},
|
|
5624
|
+
"networkId": {
|
|
5625
|
+
"type": "string"
|
|
5626
|
+
}
|
|
5627
|
+
},
|
|
5628
|
+
"required": [
|
|
5629
|
+
"vmId",
|
|
5630
|
+
"networkId"
|
|
5631
|
+
],
|
|
5632
|
+
"type": "object"
|
|
5633
|
+
}
|
|
5634
|
+
]
|
|
5635
|
+
},
|
|
5562
5636
|
"Exclude_SUPPORTED_VDI_FORMAT.qcow2_": {
|
|
5563
5637
|
"type": "string",
|
|
5564
5638
|
"enum": [
|
|
@@ -5671,6 +5745,32 @@
|
|
|
5671
5745
|
],
|
|
5672
5746
|
"type": "object"
|
|
5673
5747
|
},
|
|
5748
|
+
"CreateActionReturnType__id-Unbrand_XoVdi__91_id_93___": {
|
|
5749
|
+
"anyOf": [
|
|
5750
|
+
{
|
|
5751
|
+
"properties": {
|
|
5752
|
+
"taskId": {
|
|
5753
|
+
"type": "string"
|
|
5754
|
+
}
|
|
5755
|
+
},
|
|
5756
|
+
"required": [
|
|
5757
|
+
"taskId"
|
|
5758
|
+
],
|
|
5759
|
+
"type": "object"
|
|
5760
|
+
},
|
|
5761
|
+
{
|
|
5762
|
+
"properties": {
|
|
5763
|
+
"id": {
|
|
5764
|
+
"type": "string"
|
|
5765
|
+
}
|
|
5766
|
+
},
|
|
5767
|
+
"required": [
|
|
5768
|
+
"id"
|
|
5769
|
+
],
|
|
5770
|
+
"type": "object"
|
|
5771
|
+
}
|
|
5772
|
+
]
|
|
5773
|
+
},
|
|
5674
5774
|
"Unbrand_XoVdiSnapshot_": {
|
|
5675
5775
|
"properties": {
|
|
5676
5776
|
"$pool": {
|
|
@@ -5809,18 +5909,18 @@
|
|
|
5809
5909
|
"mode": {
|
|
5810
5910
|
"$ref": "#/components/schemas/VBD_MODE"
|
|
5811
5911
|
},
|
|
5812
|
-
"bootable": {
|
|
5813
|
-
"type": "boolean"
|
|
5814
|
-
},
|
|
5815
|
-
"empty": {
|
|
5816
|
-
"type": "boolean"
|
|
5817
|
-
},
|
|
5818
5912
|
"qos_algorithm_params": {
|
|
5819
5913
|
"$ref": "#/components/schemas/Record_string.string_"
|
|
5820
5914
|
},
|
|
5821
5915
|
"qos_algorithm_type": {
|
|
5822
5916
|
"type": "string"
|
|
5823
5917
|
},
|
|
5918
|
+
"bootable": {
|
|
5919
|
+
"type": "boolean"
|
|
5920
|
+
},
|
|
5921
|
+
"empty": {
|
|
5922
|
+
"type": "boolean"
|
|
5923
|
+
},
|
|
5824
5924
|
"unpluggable": {
|
|
5825
5925
|
"type": "boolean"
|
|
5826
5926
|
},
|
|
@@ -7826,23 +7926,50 @@
|
|
|
7826
7926
|
"type": "array"
|
|
7827
7927
|
},
|
|
7828
7928
|
"install": {
|
|
7829
|
-
"
|
|
7830
|
-
|
|
7831
|
-
"
|
|
7929
|
+
"anyOf": [
|
|
7930
|
+
{
|
|
7931
|
+
"properties": {
|
|
7932
|
+
"repository": {
|
|
7933
|
+
"type": "string"
|
|
7934
|
+
},
|
|
7935
|
+
"method": {
|
|
7936
|
+
"type": "string",
|
|
7937
|
+
"enum": [
|
|
7938
|
+
"cdrom"
|
|
7939
|
+
],
|
|
7940
|
+
"nullable": false
|
|
7941
|
+
}
|
|
7942
|
+
},
|
|
7943
|
+
"required": [
|
|
7944
|
+
"repository",
|
|
7945
|
+
"method"
|
|
7946
|
+
],
|
|
7947
|
+
"type": "object"
|
|
7832
7948
|
},
|
|
7833
|
-
|
|
7834
|
-
"
|
|
7835
|
-
|
|
7836
|
-
|
|
7837
|
-
|
|
7838
|
-
|
|
7949
|
+
{
|
|
7950
|
+
"properties": {
|
|
7951
|
+
"repository": {
|
|
7952
|
+
"type": "string",
|
|
7953
|
+
"enum": [
|
|
7954
|
+
""
|
|
7955
|
+
],
|
|
7956
|
+
"nullable": false
|
|
7957
|
+
},
|
|
7958
|
+
"method": {
|
|
7959
|
+
"type": "string",
|
|
7960
|
+
"enum": [
|
|
7961
|
+
"network"
|
|
7962
|
+
],
|
|
7963
|
+
"nullable": false
|
|
7964
|
+
}
|
|
7965
|
+
},
|
|
7966
|
+
"required": [
|
|
7967
|
+
"repository",
|
|
7968
|
+
"method"
|
|
7969
|
+
],
|
|
7970
|
+
"type": "object"
|
|
7839
7971
|
}
|
|
7840
|
-
|
|
7841
|
-
"required": [
|
|
7842
|
-
"repository",
|
|
7843
|
-
"method"
|
|
7844
|
-
],
|
|
7845
|
-
"type": "object"
|
|
7972
|
+
]
|
|
7846
7973
|
},
|
|
7847
7974
|
"cloud_config": {
|
|
7848
7975
|
"type": "string"
|
|
@@ -12026,7 +12153,7 @@
|
|
|
12026
12153
|
},
|
|
12027
12154
|
"info": {
|
|
12028
12155
|
"title": "@xen-orchestra/rest-api",
|
|
12029
|
-
"version": "0.
|
|
12156
|
+
"version": "0.24.1",
|
|
12030
12157
|
"description": "REST API to manage your XOA",
|
|
12031
12158
|
"license": {
|
|
12032
12159
|
"name": "AGPL-3.0-or-later"
|
|
@@ -18013,6 +18140,74 @@
|
|
|
18013
18140
|
"example": 42
|
|
18014
18141
|
}
|
|
18015
18142
|
]
|
|
18143
|
+
},
|
|
18144
|
+
"post": {
|
|
18145
|
+
"operationId": "CreateVif",
|
|
18146
|
+
"responses": {
|
|
18147
|
+
"201": {
|
|
18148
|
+
"description": "Resource created",
|
|
18149
|
+
"content": {
|
|
18150
|
+
"application/json": {
|
|
18151
|
+
"schema": {
|
|
18152
|
+
"properties": {
|
|
18153
|
+
"id": {
|
|
18154
|
+
"type": "string"
|
|
18155
|
+
}
|
|
18156
|
+
},
|
|
18157
|
+
"required": [
|
|
18158
|
+
"id"
|
|
18159
|
+
],
|
|
18160
|
+
"type": "object"
|
|
18161
|
+
},
|
|
18162
|
+
"examples": {
|
|
18163
|
+
"Example 1": {
|
|
18164
|
+
"value": {
|
|
18165
|
+
"id": "f028c5d4-578a-332c-394e-087aaca32dd3"
|
|
18166
|
+
}
|
|
18167
|
+
}
|
|
18168
|
+
}
|
|
18169
|
+
}
|
|
18170
|
+
}
|
|
18171
|
+
},
|
|
18172
|
+
"400": {
|
|
18173
|
+
"description": "Bad request"
|
|
18174
|
+
},
|
|
18175
|
+
"401": {
|
|
18176
|
+
"description": "Authentication required"
|
|
18177
|
+
},
|
|
18178
|
+
"404": {
|
|
18179
|
+
"description": "Resource not found"
|
|
18180
|
+
},
|
|
18181
|
+
"422": {
|
|
18182
|
+
"description": "Invalid parameters"
|
|
18183
|
+
},
|
|
18184
|
+
"500": {
|
|
18185
|
+
"description": "Internal server error, XenServer/XCP-ng error"
|
|
18186
|
+
}
|
|
18187
|
+
},
|
|
18188
|
+
"tags": [
|
|
18189
|
+
"vifs"
|
|
18190
|
+
],
|
|
18191
|
+
"security": [
|
|
18192
|
+
{
|
|
18193
|
+
"*": []
|
|
18194
|
+
}
|
|
18195
|
+
],
|
|
18196
|
+
"parameters": [],
|
|
18197
|
+
"requestBody": {
|
|
18198
|
+
"required": true,
|
|
18199
|
+
"content": {
|
|
18200
|
+
"application/json": {
|
|
18201
|
+
"schema": {
|
|
18202
|
+
"$ref": "#/components/schemas/CreateVifBody"
|
|
18203
|
+
},
|
|
18204
|
+
"example": {
|
|
18205
|
+
"networkId": "6b6ca0f5-6611-0636-4b0a-1fb1c1e96414",
|
|
18206
|
+
"vmId": "613f541c-4bed-fc77-7ca8-2db6b68f079c"
|
|
18207
|
+
}
|
|
18208
|
+
}
|
|
18209
|
+
}
|
|
18210
|
+
}
|
|
18016
18211
|
}
|
|
18017
18212
|
},
|
|
18018
18213
|
"/vifs/{id}": {
|
|
@@ -18081,6 +18276,45 @@
|
|
|
18081
18276
|
"example": "f028c5d4-578a-332c-394e-087aaca32dd3"
|
|
18082
18277
|
}
|
|
18083
18278
|
]
|
|
18279
|
+
},
|
|
18280
|
+
"delete": {
|
|
18281
|
+
"operationId": "DestroyVif",
|
|
18282
|
+
"responses": {
|
|
18283
|
+
"204": {
|
|
18284
|
+
"description": "No content"
|
|
18285
|
+
},
|
|
18286
|
+
"400": {
|
|
18287
|
+
"description": "Bad request"
|
|
18288
|
+
},
|
|
18289
|
+
"401": {
|
|
18290
|
+
"description": "Authentication required"
|
|
18291
|
+
},
|
|
18292
|
+
"404": {
|
|
18293
|
+
"description": "Resource not found"
|
|
18294
|
+
},
|
|
18295
|
+
"500": {
|
|
18296
|
+
"description": "Internal server error, XenServer/XCP-ng error"
|
|
18297
|
+
}
|
|
18298
|
+
},
|
|
18299
|
+
"tags": [
|
|
18300
|
+
"vifs"
|
|
18301
|
+
],
|
|
18302
|
+
"security": [
|
|
18303
|
+
{
|
|
18304
|
+
"*": []
|
|
18305
|
+
}
|
|
18306
|
+
],
|
|
18307
|
+
"parameters": [
|
|
18308
|
+
{
|
|
18309
|
+
"in": "path",
|
|
18310
|
+
"name": "id",
|
|
18311
|
+
"required": true,
|
|
18312
|
+
"schema": {
|
|
18313
|
+
"type": "string"
|
|
18314
|
+
},
|
|
18315
|
+
"example": "6b6ca0f5-6611-0636-4b0a-1fb1c1e96414"
|
|
18316
|
+
}
|
|
18317
|
+
]
|
|
18084
18318
|
}
|
|
18085
18319
|
},
|
|
18086
18320
|
"/vifs/{id}/alarms": {
|
|
@@ -18981,6 +19215,99 @@
|
|
|
18981
19215
|
]
|
|
18982
19216
|
}
|
|
18983
19217
|
},
|
|
19218
|
+
"/vdis/{id}/actions/migrate": {
|
|
19219
|
+
"post": {
|
|
19220
|
+
"operationId": "MigrateVdi",
|
|
19221
|
+
"responses": {
|
|
19222
|
+
"200": {
|
|
19223
|
+
"description": "Ok"
|
|
19224
|
+
},
|
|
19225
|
+
"202": {
|
|
19226
|
+
"description": "Action executed asynchronously",
|
|
19227
|
+
"content": {
|
|
19228
|
+
"application/json": {
|
|
19229
|
+
"schema": {
|
|
19230
|
+
"$ref": "#/components/schemas/CreateActionReturnType__id-Unbrand_XoVdi__91_id_93___"
|
|
19231
|
+
},
|
|
19232
|
+
"examples": {
|
|
19233
|
+
"Example 1": {
|
|
19234
|
+
"value": {
|
|
19235
|
+
"taskId": "0m7kl0j9l"
|
|
19236
|
+
}
|
|
19237
|
+
},
|
|
19238
|
+
"Example 2": {
|
|
19239
|
+
"value": {
|
|
19240
|
+
"id": "5e13f673-760e-41be-826e-620d16b7f43b"
|
|
19241
|
+
}
|
|
19242
|
+
}
|
|
19243
|
+
}
|
|
19244
|
+
}
|
|
19245
|
+
}
|
|
19246
|
+
},
|
|
19247
|
+
"400": {
|
|
19248
|
+
"description": "Bad request"
|
|
19249
|
+
},
|
|
19250
|
+
"401": {
|
|
19251
|
+
"description": "Authentication required"
|
|
19252
|
+
},
|
|
19253
|
+
"404": {
|
|
19254
|
+
"description": "Resource not found"
|
|
19255
|
+
},
|
|
19256
|
+
"500": {
|
|
19257
|
+
"description": "Internal server error, XenServer/XCP-ng error"
|
|
19258
|
+
}
|
|
19259
|
+
},
|
|
19260
|
+
"description": "Migrate a VDI to another SR.\n\nNote: After migration, the VDI will have a new ID. The new ID is returned in the response.",
|
|
19261
|
+
"tags": [
|
|
19262
|
+
"vdis"
|
|
19263
|
+
],
|
|
19264
|
+
"security": [
|
|
19265
|
+
{
|
|
19266
|
+
"*": []
|
|
19267
|
+
}
|
|
19268
|
+
],
|
|
19269
|
+
"parameters": [
|
|
19270
|
+
{
|
|
19271
|
+
"in": "path",
|
|
19272
|
+
"name": "id",
|
|
19273
|
+
"required": true,
|
|
19274
|
+
"schema": {
|
|
19275
|
+
"type": "string"
|
|
19276
|
+
},
|
|
19277
|
+
"example": "c77f9955-c1d2-4b39-aa1c-73cdb2dacb7e"
|
|
19278
|
+
},
|
|
19279
|
+
{
|
|
19280
|
+
"in": "query",
|
|
19281
|
+
"name": "sync",
|
|
19282
|
+
"required": false,
|
|
19283
|
+
"schema": {
|
|
19284
|
+
"type": "boolean"
|
|
19285
|
+
}
|
|
19286
|
+
}
|
|
19287
|
+
],
|
|
19288
|
+
"requestBody": {
|
|
19289
|
+
"required": true,
|
|
19290
|
+
"content": {
|
|
19291
|
+
"application/json": {
|
|
19292
|
+
"schema": {
|
|
19293
|
+
"properties": {
|
|
19294
|
+
"srId": {
|
|
19295
|
+
"type": "string"
|
|
19296
|
+
}
|
|
19297
|
+
},
|
|
19298
|
+
"required": [
|
|
19299
|
+
"srId"
|
|
19300
|
+
],
|
|
19301
|
+
"type": "object"
|
|
19302
|
+
},
|
|
19303
|
+
"example": {
|
|
19304
|
+
"srId": "4cb0d74e-a7c1-0b7d-46e3-09382c012abb"
|
|
19305
|
+
}
|
|
19306
|
+
}
|
|
19307
|
+
}
|
|
19308
|
+
}
|
|
19309
|
+
}
|
|
19310
|
+
},
|
|
18984
19311
|
"/vdis/{id}/tags/{tag}": {
|
|
18985
19312
|
"put": {
|
|
18986
19313
|
"operationId": "PutVdiTag",
|
|
@@ -20357,6 +20684,140 @@
|
|
|
20357
20684
|
]
|
|
20358
20685
|
}
|
|
20359
20686
|
},
|
|
20687
|
+
"/vbds/{id}/actions/connect": {
|
|
20688
|
+
"post": {
|
|
20689
|
+
"operationId": "ConnectVbd",
|
|
20690
|
+
"responses": {
|
|
20691
|
+
"202": {
|
|
20692
|
+
"description": "Action executed asynchronously",
|
|
20693
|
+
"content": {
|
|
20694
|
+
"application/json": {
|
|
20695
|
+
"schema": {
|
|
20696
|
+
"$ref": "#/components/schemas/CreateActionReturnType_void_"
|
|
20697
|
+
},
|
|
20698
|
+
"examples": {
|
|
20699
|
+
"Example 1": {
|
|
20700
|
+
"value": {
|
|
20701
|
+
"taskId": "0m7kl0j9l"
|
|
20702
|
+
}
|
|
20703
|
+
}
|
|
20704
|
+
}
|
|
20705
|
+
}
|
|
20706
|
+
}
|
|
20707
|
+
},
|
|
20708
|
+
"204": {
|
|
20709
|
+
"description": "No content"
|
|
20710
|
+
},
|
|
20711
|
+
"400": {
|
|
20712
|
+
"description": "Bad request"
|
|
20713
|
+
},
|
|
20714
|
+
"401": {
|
|
20715
|
+
"description": "Authentication required"
|
|
20716
|
+
},
|
|
20717
|
+
"404": {
|
|
20718
|
+
"description": "Resource not found"
|
|
20719
|
+
},
|
|
20720
|
+
"500": {
|
|
20721
|
+
"description": "Internal server error, XenServer/XCP-ng error"
|
|
20722
|
+
}
|
|
20723
|
+
},
|
|
20724
|
+
"description": "Hotplug the VBD, dynamically attaching it to the running VM",
|
|
20725
|
+
"tags": [
|
|
20726
|
+
"vbds"
|
|
20727
|
+
],
|
|
20728
|
+
"security": [
|
|
20729
|
+
{
|
|
20730
|
+
"*": []
|
|
20731
|
+
}
|
|
20732
|
+
],
|
|
20733
|
+
"parameters": [
|
|
20734
|
+
{
|
|
20735
|
+
"in": "path",
|
|
20736
|
+
"name": "id",
|
|
20737
|
+
"required": true,
|
|
20738
|
+
"schema": {
|
|
20739
|
+
"type": "string"
|
|
20740
|
+
},
|
|
20741
|
+
"example": "f07ab729-c0e8-721c-45ec-f11276377030"
|
|
20742
|
+
},
|
|
20743
|
+
{
|
|
20744
|
+
"in": "query",
|
|
20745
|
+
"name": "sync",
|
|
20746
|
+
"required": false,
|
|
20747
|
+
"schema": {
|
|
20748
|
+
"type": "boolean"
|
|
20749
|
+
}
|
|
20750
|
+
}
|
|
20751
|
+
]
|
|
20752
|
+
}
|
|
20753
|
+
},
|
|
20754
|
+
"/vbds/{id}/actions/disconnect": {
|
|
20755
|
+
"post": {
|
|
20756
|
+
"operationId": "DisconnectVbd",
|
|
20757
|
+
"responses": {
|
|
20758
|
+
"202": {
|
|
20759
|
+
"description": "Action executed asynchronously",
|
|
20760
|
+
"content": {
|
|
20761
|
+
"application/json": {
|
|
20762
|
+
"schema": {
|
|
20763
|
+
"$ref": "#/components/schemas/CreateActionReturnType_void_"
|
|
20764
|
+
},
|
|
20765
|
+
"examples": {
|
|
20766
|
+
"Example 1": {
|
|
20767
|
+
"value": {
|
|
20768
|
+
"taskId": "0m7kl0j9l"
|
|
20769
|
+
}
|
|
20770
|
+
}
|
|
20771
|
+
}
|
|
20772
|
+
}
|
|
20773
|
+
}
|
|
20774
|
+
},
|
|
20775
|
+
"204": {
|
|
20776
|
+
"description": "No content"
|
|
20777
|
+
},
|
|
20778
|
+
"400": {
|
|
20779
|
+
"description": "Bad request"
|
|
20780
|
+
},
|
|
20781
|
+
"401": {
|
|
20782
|
+
"description": "Authentication required"
|
|
20783
|
+
},
|
|
20784
|
+
"404": {
|
|
20785
|
+
"description": "Resource not found"
|
|
20786
|
+
},
|
|
20787
|
+
"500": {
|
|
20788
|
+
"description": "Internal server error, XenServer/XCP-ng error"
|
|
20789
|
+
}
|
|
20790
|
+
},
|
|
20791
|
+
"description": "Hot-unplug the VBD, dynamically detaching it from the running VM",
|
|
20792
|
+
"tags": [
|
|
20793
|
+
"vbds"
|
|
20794
|
+
],
|
|
20795
|
+
"security": [
|
|
20796
|
+
{
|
|
20797
|
+
"*": []
|
|
20798
|
+
}
|
|
20799
|
+
],
|
|
20800
|
+
"parameters": [
|
|
20801
|
+
{
|
|
20802
|
+
"in": "path",
|
|
20803
|
+
"name": "id",
|
|
20804
|
+
"required": true,
|
|
20805
|
+
"schema": {
|
|
20806
|
+
"type": "string"
|
|
20807
|
+
},
|
|
20808
|
+
"example": "f07ab729-c0e8-721c-45ec-f11276377030"
|
|
20809
|
+
},
|
|
20810
|
+
{
|
|
20811
|
+
"in": "query",
|
|
20812
|
+
"name": "sync",
|
|
20813
|
+
"required": false,
|
|
20814
|
+
"schema": {
|
|
20815
|
+
"type": "boolean"
|
|
20816
|
+
}
|
|
20817
|
+
}
|
|
20818
|
+
]
|
|
20819
|
+
}
|
|
20820
|
+
},
|
|
20360
20821
|
"/users": {
|
|
20361
20822
|
"get": {
|
|
20362
20823
|
"operationId": "GetUsers",
|
package/package.json
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
"main": "./dist/index.mjs",
|
|
7
7
|
"name": "@xen-orchestra/rest-api",
|
|
8
8
|
"homepage": "https://github.com/vatesfr/xen-orchestra/tree/master/@xen-orchestra/rest-api",
|
|
9
|
-
"version": "0.
|
|
9
|
+
"version": "0.24.1",
|
|
10
10
|
"description": "REST API to manage your XOA",
|
|
11
11
|
"license": "AGPL-3.0-or-later",
|
|
12
12
|
"private": false,
|
|
@@ -35,10 +35,10 @@
|
|
|
35
35
|
"dependencies": {
|
|
36
36
|
"@vates/async-each": "^1.0.1",
|
|
37
37
|
"@vates/task": "^0.6.1",
|
|
38
|
-
"@vates/types": "^1.
|
|
39
|
-
"@xen-orchestra/backups": "^0.68.
|
|
38
|
+
"@vates/types": "^1.18.0",
|
|
39
|
+
"@xen-orchestra/backups": "^0.68.1",
|
|
40
40
|
"@xen-orchestra/log": "^0.7.1",
|
|
41
|
-
"@xen-orchestra/xapi": "^8.6.
|
|
41
|
+
"@xen-orchestra/xapi": "^8.6.5",
|
|
42
42
|
"complex-matcher": "^1.0.0",
|
|
43
43
|
"golike-defer": "^0.5.1",
|
|
44
44
|
"inversify": "^6.2.2",
|