vsphere-infra
Version:
426 lines • 22.1 kB
JavaScript
"use strict";
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.VsphereCaller = void 0;
const managed_objects_1 = require("./managed.objects");
const soap_parser_1 = require("./soap.parser");
const ts_basis_1 = require("ts-basis");
class VsphereCaller extends ts_basis_1.ix.Entity {
constructor($dc, client) {
super('vcenter-api');
this.topError = null;
this.topErrorBody = '';
this.topErrorMessage = '';
this.topErrorDetail = '';
this.errors = [];
this.options = { forever: true, timeout: 30000 };
this.$dc = $dc;
this.client = client;
$dc.lifecycle.manage(this);
}
resetData() {
this.serviceContent = null;
this.containerView = null;
this.inventoryData = null;
this.inventoryRaw = null;
this.inventoryStubsData = null;
this.inventoryStubsRaw = null;
}
errorCodeHandle(message) {
const dc = this.$dc;
const has = part => message.indexOf(part) >= 0;
if (has('ManagedObjectNotFoundFault')) {
if (has('vim.view.ContainerView:session') &&
has('has already been deleted or has not been completely created')) {
this.getDefaultContainerView(true);
dc.emitEvent(dc.sessionNotValid$, { type: 'not_found' });
return;
}
else {
const moValue = message.split('</obj>')[0].split('>').pop();
const iid = (0, managed_objects_1.iidParse)(moValue);
dc.emitEvent(dc.entryNotFound$, { iid, value: moValue });
return;
}
}
else if (has('Unknown mo value session[')) {
this.getDefaultContainerView(true);
dc.emitEvent(dc.sessionNotValid$, { type: 'unknown_mo' });
return;
}
return 'YES_DEBUG_OUTPUT';
}
resolveError(error, resolve) {
this.topError = error;
if (error.body) {
this.topErrorBody = error.body;
try {
if (error.body.indexOf('<faultstring>') >= 0) {
this.topErrorMessage = error.body.split('<faultstring>')[1].split('</faultstring>')[0];
this.topErrorDetail = error.body.split('<detail>')[1].split('</detail>')[0];
let doOutput = 'YES_DEBUG_OUTPUT';
if (this.topErrorDetail) {
doOutput = this.errorCodeHandle(this.topErrorDetail);
}
if (doOutput) {
this.$dc.debugOutput(new Error(this.topErrorDetail));
}
}
else {
let handled = false;
if (error instanceof Error) {
if (error.message === 'ESOCKETTIMEDOUT') {
handled = true;
this.$dc.debugOutput('request.js error code: ESOCKETTIMEDOUT');
}
}
else {
}
if (!handled) {
this.$dc.ix.pushError(new Error(`Unknown error: ${JSON.stringify(error)}`), 2);
}
}
}
catch (e) {
this.$dc.ix.pushError(e);
}
}
else {
if (error instanceof Error) {
this.$dc.ix.pushError(error, 2);
}
else {
this.$dc.ix.pushError(new Error(`Unknown error: ${JSON.stringify(error)}`), 2);
}
}
resolve(null);
}
getServiceContent() {
return __awaiter(this, void 0, void 0, function* () {
if (!this.serviceContent) {
this.serviceContent = (0, ts_basis_1.promise)((resolve) => __awaiter(this, void 0, void 0, function* () {
this.client.VimService.VimPort.RetrieveServiceContent((0, soap_parser_1.paramFilter)({
_this: 'ServiceInstance'
}), (e, r) => __awaiter(this, void 0, void 0, function* () {
if (e) {
return this.resolveError(e, resolve);
}
if (!r) {
return this.resolveError(new Error('Emtpy response'), resolve);
}
this.serviceContent = r.returnval;
this.$dc.debugOutput(`fetched service content`);
return resolve(r.returnval);
}), this.options);
}));
}
return yield Promise.resolve(this.serviceContent);
});
}
getDefaultContainerView(noCache = false) {
return __awaiter(this, void 0, void 0, function* () {
if (!this.containerView || noCache) {
this.containerView = (0, ts_basis_1.promise)((resolve) => __awaiter(this, void 0, void 0, function* () {
if (!(yield this.getServiceContent())) {
return resolve(null);
}
this.client.VimService.VimPort.CreateContainerView((0, soap_parser_1.paramFilter)({
_this: (0, soap_parser_1.ref)(this.serviceContent.viewManager),
container: (0, soap_parser_1.ref)(this.serviceContent.rootFolder),
recursive: true
}), (e, r) => __awaiter(this, void 0, void 0, function* () {
if (e) {
return this.resolveError(e, resolve);
}
if (!r) {
return this.resolveError(new Error('Emtpy response'), resolve);
}
this.containerView = r.returnval;
this.$dc.debugOutput(`fetched default container view (${this.containerView.$value})`);
return resolve(r.returnval);
}), this.options);
}));
}
return yield Promise.resolve(this.containerView);
});
}
getInventoryStubs(noCache = false) {
return __awaiter(this, void 0, void 0, function* () {
if (!this.inventoryStubsData || noCache) {
this.inventoryStubsData = (0, ts_basis_1.promise)((resolve) => __awaiter(this, void 0, void 0, function* () {
if (!(yield this.getDefaultContainerView())) {
return resolve(null);
}
this.client.VimService.VimPort.RetrievePropertiesEx((0, soap_parser_1.paramFilter)({
_this: (0, soap_parser_1.ref)(this.serviceContent.propertyCollector),
specSet: [
(0, soap_parser_1.xsi)('PropertyFilterSpec', {
propSet: [
(0, soap_parser_1.xsi)('PropertySpec', { type: 'Folder', all: false, pathSet: ['value'] }),
(0, soap_parser_1.xsi)('PropertySpec', { type: 'HostSystem', all: false, pathSet: ['value'] }),
(0, soap_parser_1.xsi)('PropertySpec', { type: 'Datacenter', all: false, pathSet: ['value'] }),
(0, soap_parser_1.xsi)('PropertySpec', { type: 'ComputeResource', all: false, pathSet: ['value'] }),
(0, soap_parser_1.xsi)('PropertySpec', { type: 'Network', all: false, pathSet: ['value'] }),
(0, soap_parser_1.xsi)('PropertySpec', { type: 'Datastore', all: false, pathSet: ['value'] }),
(0, soap_parser_1.xsi)('PropertySpec', { type: 'VirtualMachine', all: false, pathSet: ['value'] }),
(0, soap_parser_1.xsi)('PropertySpec', { type: 'ResourcePool', all: false, pathSet: ['value'] }),
(0, soap_parser_1.xsi)('PropertySpec', { type: 'VirtualApp', all: false, pathSet: ['value'] }),
(0, soap_parser_1.xsi)('PropertySpec', { type: 'DistributedVirtualSwitch', all: false, pathSet: ['value'] }),
],
objectSet: [
(0, soap_parser_1.xsi)('ObjectSpec', {
obj: (0, soap_parser_1.ref)(this.containerView), skip: true,
selectSet: [(0, soap_parser_1.xsi)('TraversalSpec', { type: 'ContainerView', path: 'view', skip: false })]
})
],
})
],
options: { maxObjects: 1000000 },
}), (e, r) => __awaiter(this, void 0, void 0, function* () {
if (e) {
return this.resolveError(e, resolve);
}
if (!r) {
return this.resolveError(new Error('Emtpy response'), resolve);
}
const pages = yield this.getAllPages(r.returnval);
if (!pages) {
return resolve(null);
}
this.inventoryStubsRaw = pages.rawData;
this.inventoryStubsData = pages.data;
return resolve(this.inventoryStubsData);
}), this.options);
}));
}
return yield Promise.resolve(this.inventoryStubsData);
});
}
getInventoryData(noCache = false) {
return __awaiter(this, void 0, void 0, function* () {
if (!this.inventoryData || noCache) {
this.inventoryData = (0, ts_basis_1.promise)((resolve) => __awaiter(this, void 0, void 0, function* () {
if (!(yield this.getDefaultContainerView())) {
return resolve(null);
}
this.client.VimService.VimPort.RetrievePropertiesEx((0, soap_parser_1.paramFilter)({
_this: (0, soap_parser_1.ref)(this.serviceContent.propertyCollector),
specSet: [
(0, soap_parser_1.xsi)('PropertyFilterSpec', {
propSet: [
(0, soap_parser_1.xsi)('PropertySpec', { type: 'Folder', all: true }),
(0, soap_parser_1.xsi)('PropertySpec', { type: 'HostSystem', all: true }),
(0, soap_parser_1.xsi)('PropertySpec', { type: 'Datacenter', all: true }),
(0, soap_parser_1.xsi)('PropertySpec', { type: 'ComputeResource', all: true }),
(0, soap_parser_1.xsi)('PropertySpec', { type: 'Network', all: true }),
(0, soap_parser_1.xsi)('PropertySpec', { type: 'Datastore', all: true }),
(0, soap_parser_1.xsi)('PropertySpec', { type: 'VirtualMachine', all: true }),
(0, soap_parser_1.xsi)('PropertySpec', { type: 'ResourcePool', all: true }),
(0, soap_parser_1.xsi)('PropertySpec', { type: 'VirtualApp', all: true }),
(0, soap_parser_1.xsi)('PropertySpec', { type: 'DistributedVirtualSwitch', all: true }),
],
objectSet: [
(0, soap_parser_1.xsi)('ObjectSpec', {
obj: (0, soap_parser_1.ref)(this.containerView), skip: true,
selectSet: [(0, soap_parser_1.xsi)('TraversalSpec', { type: 'ContainerView', path: 'view', skip: false })]
})
],
})
],
options: { maxObjects: 1000000 },
}), (e, r) => __awaiter(this, void 0, void 0, function* () {
if (e) {
return this.resolveError(e, resolve);
}
if (!r) {
return this.resolveError(new Error('Emtpy response'), resolve);
}
const pages = yield this.getAllPages(r.returnval);
if (!pages) {
return resolve(null);
}
this.inventoryRaw = pages.rawData;
this.inventoryData = pages.data;
this.$dc.lockStubs();
const allProms = [];
for (const moData of this.inventoryData) {
const moTypeName = moData.iid.split(':')[1];
const moClass = (0, managed_objects_1.getMoTypeByName)(moTypeName);
const mo = new moClass(this.$dc, moData);
if (mo) {
allProms.push(mo.$initPending);
}
}
this.$dc.unlockStubs();
this.$dc.inventoryPending = (0, ts_basis_1.promise)((invResolve) => __awaiter(this, void 0, void 0, function* () {
yield Promise.all(allProms);
yield this.$dc.postInventoryDataFetch();
this.$dc.inventoryPending = false;
invResolve(false);
}));
return resolve(r.returnval.objects);
}), this.options);
}));
}
return yield Promise.resolve(this.inventoryData);
});
}
getInventory(noCache = false) {
return __awaiter(this, void 0, void 0, function* () {
this.$dc.debugOutput(`mapping inventory...`);
yield this.getInventoryData(noCache);
yield Promise.resolve(this.$dc.inventoryPending);
const hostCount = Object.keys(this.$dc.inventory.hostSystem).length;
const foldersCount = Object.keys(this.$dc.inventory.folder).length;
const vmCount = Object.keys(this.$dc.inventory.virtualMachine).length;
this.$dc.debugOutput(`finished mapping inventory (VMs=${vmCount}, Folders=${foldersCount}, Hosts=${hostCount})`);
this.$dc.inventoryChangedLast = Date.now();
this.$dc.preserializeInventory();
return this.$dc;
});
}
getManagedObjectData(target) {
return __awaiter(this, void 0, void 0, function* () {
const stub = (0, soap_parser_1.ref)(target);
const moType = stub.attributes.type;
return yield (0, ts_basis_1.promise)((resolve) => __awaiter(this, void 0, void 0, function* () {
if (!(yield this.getDefaultContainerView())) {
return resolve(null);
}
this.client.VimService.VimPort.RetrievePropertiesEx((0, soap_parser_1.paramFilter)({
_this: (0, soap_parser_1.ref)(this.serviceContent.propertyCollector),
specSet: [
(0, soap_parser_1.xsi)('PropertyFilterSpec', {
propSet: [(0, soap_parser_1.xsi)('PropertySpec', { type: moType, all: true }),],
objectSet: [(0, soap_parser_1.xsi)('ObjectSpec', { obj: stub })],
})
],
options: { maxObjects: 1 },
}), (e, r) => __awaiter(this, void 0, void 0, function* () {
if (e) {
return this.resolveError(e, resolve);
}
if (!r) {
return this.resolveError(new Error('Emtpy response'), resolve);
}
const targetData = (yield (0, soap_parser_1.parseObjects)(r.returnval.objects))[0];
return resolve(targetData);
}), this.options);
}));
});
}
prop(target, prop) {
return __awaiter(this, void 0, void 0, function* () {
const targetStub = (0, soap_parser_1.ref)(target);
let targetType = targetStub.attributes.type;
if (!targetType) {
targetType = target._type;
}
if (!targetType) {
this.$dc.debugOutput(`unknown target type: ${JSON.stringify(targetStub)}`);
return null;
}
return yield (0, ts_basis_1.promise)((resolve) => __awaiter(this, void 0, void 0, function* () {
if (!(yield this.getDefaultContainerView())) {
return resolve(null);
}
this.client.VimService.VimPort.RetrievePropertiesEx((0, soap_parser_1.paramFilter)({
_this: (0, soap_parser_1.ref)(this.serviceContent.propertyCollector),
specSet: [
(0, soap_parser_1.xsi)('PropertyFilterSpec', {
propSet: [(0, soap_parser_1.xsi)('PropertySpec', { type: targetType, all: [prop] }),],
objectSet: [(0, soap_parser_1.xsi)('ObjectSpec', { obj: targetStub }),],
})
],
options: { maxObjects: 1 },
}), (e, r) => __awaiter(this, void 0, void 0, function* () {
if (e) {
return this.resolveError(e, resolve);
}
if (!r) {
return this.resolveError(new Error('Emtpy response'), resolve);
}
const list = r.returnval.objects;
if (!list || list.length === 0) {
return null;
}
return resolve(r.returnval.objects);
}), this.options);
}));
});
}
propChain(target, ...props) {
return __awaiter(this, void 0, void 0, function* () {
let prevTarget = target;
for (const prop of props) {
target = yield this.prop(target, prop);
if (target === null) {
this.$dc.debugOutput(`Cannot fetch '${prop}' of prop chain '${props.join('.')}' on target ${JSON.stringify((0, soap_parser_1.ref)(prevTarget))}`);
return null;
}
prevTarget = target;
}
return target;
});
}
getAllPages(returnVal, stepDelayMs = 100) {
return __awaiter(this, void 0, void 0, function* () {
const objectsPagesRaw = [returnVal.objects];
const objectsPages = [yield (0, soap_parser_1.parseObjects)(returnVal.objects)];
let token = returnVal.token;
while (token) {
yield sleepMs(stepDelayMs);
const page = yield this.furtherRetrievePages(token);
if (!page) {
return null;
}
objectsPagesRaw.push(page.objects);
objectsPages.push(yield (0, soap_parser_1.parseObjects)(page.objects));
if (page.token === token) {
return null;
}
token = page.token;
}
const result = {
rawData: [].concat(...objectsPagesRaw),
data: [].concat(...objectsPages),
};
return result;
});
}
furtherRetrievePages(furtherToken) {
return __awaiter(this, void 0, void 0, function* () {
return yield (0, ts_basis_1.promise)((resolve) => __awaiter(this, void 0, void 0, function* () {
if (!(yield this.getDefaultContainerView())) {
return resolve(null);
}
this.client.VimService.VimPort.ContinueRetrievePropertiesEx((0, soap_parser_1.paramFilter)({
_this: (0, soap_parser_1.ref)(this.serviceContent.propertyCollector), token: furtherToken
}), (e, r) => __awaiter(this, void 0, void 0, function* () {
if (e) {
return this.resolveError(e, resolve);
}
if (!r) {
return this.resolveError(new Error('Emtpy response'), resolve);
}
resolve({ objects: r.returnval.objects, token: r.returnval.token });
}), this.options);
}));
});
}
}
exports.VsphereCaller = VsphereCaller;
function sleepMs(ms) {
return __awaiter(this, void 0, void 0, function* () {
return (0, ts_basis_1.promise)(resolve => setTimeout(resolve, ms));
});
}
//# sourceMappingURL=vsphere.caller.js.map