UNPKG

vsphere-infra

Version:

426 lines 22.1 kB
"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