vsphere-infra
Version:
963 lines • 37.7 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());
});
};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.VsphereBehaviorController = exports.VsphereInfra = exports.VsphereDatacenter = void 0;
const connection_1 = require("./connection");
const soap_parser_1 = require("./soap.parser");
const managed_objects_1 = require("./managed.objects");
const axios_1 = __importDefault(require("axios"));
const ssl_trust_1 = require("ssl-trust");
const ts_basis_1 = require("ts-basis");
class VsphereDatacenter extends ts_basis_1.ix.ReconnEntity {
static fromTargetInfo(target, vinfra) {
return __awaiter(this, void 0, void 0, function* () {
if (!target.key) {
return null;
}
let dc;
const datacenterData = vinfra.datacenterData;
const behavior = vinfra.behavior;
if (!datacenterData[target.key]) {
dc = datacenterData[target.key] = new VsphereDatacenter(target.key, vinfra);
dc.verbose = behavior.verbose;
dc.readonlyMode = behavior.readonlyMode;
dc.webhooks = behavior.webhooks;
dc.jsonLogs = behavior.jsonLogs;
dc.sourceTarget = target;
if (target.cert) {
if (target.cert.trim().startsWith('-----BEGIN CERTIFICATE-----')) {
yield ssl_trust_1.SSLTrust.trustCert(target.cert);
}
else {
yield ssl_trust_1.SSLTrust.trustCertFile(target.cert);
}
}
}
else {
dc.sourceTarget = target;
}
return dc;
});
}
constructor(key, vinfra) {
var _a, _b;
super(`vsphere-${key}`);
this.ready = false;
this.readyResolver = null;
this.readyPromise = null;
this.connections = [];
this.connectionPickIndex = 0;
this.disconnected = false;
this.inventoryPending = true;
this.inventoryStubHunts = {};
this.inventoryInProgress = false;
this.inventoryCheckInProgress = 0;
this.inventoryCheckInterval = 30;
this.inventoryCheckLast = 0;
this.inventoryChangedLast = 0;
this.inventoryWatchStarted = false;
this.inventoryWatchChecker = null;
this.inventory = {
byIID: {},
byGUID: {},
folder: {},
hostSystem: {},
datacenter: {},
network: {},
datastore: {},
computeResource: {},
resourcePool: {},
virtualApp: {},
virtualMachine: {},
virtualSwitch: {},
deleted: [],
};
this.index = {
byName: {},
byIP: {},
};
this.utilization = null;
this.u9nCheckInterval = 60;
this.u9nCheckLast = 0;
this.u9nHistory = [];
this.u9nHistoryMaxKept = 1440;
this.u9nWithHistory = true;
this.u9nWatchStarted = false;
this.u9nWatchChecker = null;
this.readonlyMode = false;
this.queriedIIDs = [];
this.queriedStubs = [];
this.verbose = false;
this.jsonLogs = false;
this.webhooks = [];
this.key = key;
this.vinfra = vinfra;
this.ix.reconn.on.defunct = () => {
this.debugOutput(`This vCenter (${this.key}) class is going defunct after too many errors.`);
};
this.ix.reconn.on.restore = () => {
this.debugOutput(`This vCenter (${this.key}) has come back from defunct state.`);
};
this.ix.reconn.actions.reset = () => __awaiter(this, void 0, void 0, function* () {
this.debugOutput(`Errors heating up above ${this.ix.reconn.config.resetThreshold}; `
+ `resetting main connection... (${this.ix.reconn.defunctHeat.value.toPrecision(2)})`);
yield this.resetConnection(true);
});
this.ix.reconn.actions.attemptToRestore = () => __awaiter(this, void 0, void 0, function* () {
return (yield this.resetConnection()) ? true : false;
});
if ((_b = (_a = this.vinfra) === null || _a === void 0 ? void 0 : _a.behavior) === null || _b === void 0 ? void 0 : _b.reconnect) {
this.ix.reconn.setConfigSource(this.vinfra.behavior.reconnect);
}
vinfra.lifecycle.manage(this);
this.readyResetState();
}
get datacenterGeneric$() { return this.rx('datacenter_generic').obs(); }
get connectionReset$() { return this.rx('connection:reset').obs(); }
get connectionDefunct$() { return this.rx('connection:defunct').obs(); }
get connectionRecover$() { return this.rx('connection:recover').obs(); }
get sessionNotValid$() { return this.rx('session:not_valid').obs(); }
get entryRegister$() { return this.rx('entry:register').obs(); }
get entryRefresh$() { return this.rx('entry:refresh').obs(); }
get entryMove$() { return this.rx('entry:move').obs(); }
get entryNew$() { return this.rx('entry:new').obs(); }
get entryDelete$() { return this.rx('entry:delete').obs(); }
get entryNotFound$() { return this.rx('entry:not_found').obs(); }
get u9nUpdate$() { return this.rx('u9n:update').obs(); }
get u9n() { return this.utilization; }
procureConnection(timeout = this.vinfra.behavior.connection.timeout, reuseClient = false) {
return __awaiter(this, void 0, void 0, function* () {
if (!timeout && timeout !== 0) {
timeout = this.vinfra.behavior.connection.timeout;
}
let connection;
if (reuseClient && this.connections[0]) {
connection = this.connections[0];
const loggedIn = yield retry(timeout, () => __awaiter(this, void 0, void 0, function* () { return yield connection.login(this.sourceTarget.username, this.sourceTarget.password); }));
if (!loggedIn) {
connection = yield this.procureConnection(timeout, false);
}
else {
connection.api.resetData();
}
}
else {
connection = new connection_1.VsphereConnection(this, this.sourceTarget.url, {}, VsphereInfra.granted);
try {
const connected = yield retry(timeout, () => __awaiter(this, void 0, void 0, function* () { return yield connection.connect(); }));
if (!connected) {
this.debugOutput(`unable to connect to ${this.sourceTarget.url}`);
return null;
}
const loggedIn = yield retry(timeout, () => __awaiter(this, void 0, void 0, function* () { return yield connection.login(this.sourceTarget.username, this.sourceTarget.password); }));
if (!loggedIn) {
return null;
}
}
catch (e) {
this.debugOutput(e);
return null;
}
this.debugOutput(`successfully logged in as ${this.sourceTarget.username}`);
}
return connection;
});
}
resetConnection(reuseClient = false) {
return __awaiter(this, void 0, void 0, function* () {
this.readyResetState();
const conn = yield this.procureConnection(null, reuseClient);
if (!conn) {
this.ix.pushError(new Error(`unable to procure authenticated connection`), 10);
this.readyFulfill(false);
return null;
}
this.connections.length = 0;
this.connections.push(conn);
this.readyFulfill(true);
return conn;
});
}
initializeConnection() {
return __awaiter(this, void 0, void 0, function* () {
return yield this.resetConnection();
});
}
pickConnection() {
if (this.connections.length === 0) {
return null;
}
const idx = (++this.connectionPickIndex) % this.connections.length;
return this.connections[idx];
}
lockStubs() {
this.unlockStubs();
this.inventoryStubPending = new Promise(resolve => { this.inventoryStubPendingResolver = resolve; });
}
unlockStubs() {
if (this.inventoryStubPendingResolver) {
this.inventoryStubPendingResolver(false);
}
this.inventoryStubPendingResolver = null;
}
getInventory() {
return __awaiter(this, void 0, void 0, function* () {
if (this.inventoryInProgress) {
return this;
}
try {
this.inventoryInProgress = true;
const conn = this.pickConnection();
if (!conn) {
return this.errorNoConnection();
}
yield conn.api.getInventory(true);
}
catch (e) {
this.ix.pushError(e);
}
this.inventoryInProgress = false;
return this;
});
}
trimDeleted() {
this.inventory.deleted = this.inventory.deleted.filter(mo => {
return (Date.now() - mo.$deletedTime < 3600000);
});
}
cleanInventory() {
return __awaiter(this, void 0, void 0, function* () {
this.debugOutput(`cleaning inventory...`);
for (const iid of Object.keys(this.inventory.byIID)) {
this.inventory.byIID[iid].unregister();
}
const deletedListSaved = this.inventory.deleted;
this.inventoryPending = true;
this.inventoryStubPendingResolver = null;
this.inventoryStubPending = null;
this.inventoryStubHunts = {};
this.inventoryCheckInProgress = 0;
this.inventory = {
byIID: {},
byGUID: {},
folder: {},
hostSystem: {},
datacenter: {},
network: {},
datastore: {},
computeResource: {},
resourcePool: {},
virtualApp: {},
virtualMachine: {},
virtualSwitch: {},
deleted: deletedListSaved
};
this.index = {
byName: {},
byIP: {},
};
this.debugOutput(`unregistered all inventory entries.`);
});
}
getInventoryIIDs() {
return __awaiter(this, void 0, void 0, function* () {
try {
const conn = this.pickConnection();
if (!conn) {
return this.errorNoConnection();
}
const moStubs = yield conn.api.getInventoryStubs(true);
if (!moStubs) {
return null;
}
this.queriedStubs = moStubs;
this.queriedIIDs = this.queriedStubs.map(item => item.iid);
}
catch (e) {
this.ix.pushError(e);
}
return this.queriedIIDs;
});
}
checkInventory() {
return __awaiter(this, void 0, void 0, function* () {
const conn = this.pickConnection();
if (!conn) {
return this.errorNoConnection();
}
if (this.inventoryCheckInProgress) {
if (Date.now() - this.inventoryCheckInProgress > 30000) {
this.ix.pushError(new Error(`inventory check was taking too long; attempting a retry.`));
}
else {
this.ix.pushError(new Error(`inventory check is already in progress.`), 0.5);
return;
}
}
this.inventoryCheckInProgress = Date.now();
const iids = yield this.getInventoryIIDs();
if (!iids) {
this.inventoryCheckInProgress = 0;
this.ix.pushError(new Error(`inventory check failed; entities stub list fetch failed.`), 0.5);
return;
}
const newEntries = [];
const deletedEntries = [];
const iidsMap = {};
for (const iid of iids) {
iidsMap[iid] = true;
if (!this.inventory.byIID[iid]) {
newEntries.push(iid);
}
}
for (const iid of Object.keys(this.inventory.byIID)) {
if (iid === '$mo:Folder:group-d1') {
continue;
}
if (!iidsMap[iid]) {
deletedEntries.push(iid);
}
}
if (newEntries.length > 0 || deletedEntries.length > 0) {
this.debugOutput(`inventory change: ${newEntries.length} new entries and ${deletedEntries.length} deleted entries.`);
if (deletedEntries.length > 0) {
for (const iid of deletedEntries) {
const mo = this.inventory.byIID[iid];
if (!mo) {
continue;
}
mo.unregister();
this.emitEvent(this.entryDelete$, { target: mo.entitySummaryHeaders() });
}
}
if (newEntries.length > 0) {
const entries = yield this.getMany(newEntries);
for (const mo of entries) {
this.emitEvent(this.entryNew$, { target: mo.entitySummaryHeaders() });
}
}
this.inventoryChangedLast = Date.now();
this.preserializeInventory();
}
else {
}
this.trimDeleted();
this.inventoryCheckInProgress = 0;
});
}
preserializeInventory() {
const serializedInv = {};
for (const guid of Object.keys(this.inventory.byGUID)) {
const mo = this.inventory.byGUID[guid];
if (!mo) {
continue;
}
serializedInv[guid] = mo.entitySummaryHeaders();
}
this.inventorySerialized = JSON.stringify(serializedInv);
}
postInventoryDataFetch() {
return __awaiter(this, void 0, void 0, function* () {
const dsList = Object.keys(this.inventory.datastore).map(key => this.inventory.datastore[key]);
for (const ds of dsList) {
if (ds.info.aliasOf === ds.info.containerId) {
continue;
}
ds.aliasOf = dsList.filter(ds2 => {
if (ds2.info.containerId === ds.info.aliasOf) {
if (ds2.aliases.indexOf(ds) === -1) {
ds2.aliases.push(ds);
}
return true;
}
})[0];
}
const resPoolList = Object.keys(this.inventory.resourcePool).map(key => this.inventory.resourcePool[key]);
for (const resPool of resPoolList) {
if (resPool.parent) {
continue;
}
resPool.parent = resPool.owner;
}
const vAppList = Object.keys(this.inventory.virtualApp).map(key => this.inventory.virtualApp[key]);
for (const vApp of vAppList) {
if (vApp.parent) {
continue;
}
vApp.parent = vApp.owner;
}
});
}
fetchNewMo(iid, moTypeClass, stubLock = true, ignoreError = false) {
return __awaiter(this, void 0, void 0, function* () {
iid = (0, managed_objects_1.iidParse)(iid);
if (this.inventoryStubHunts[iid]) {
return this.inventoryStubHunts[iid];
}
this.inventoryStubHunts[iid] = (0, ts_basis_1.promise)((resolve) => __awaiter(this, void 0, void 0, function* () {
try {
const conn = this.pickConnection();
if (!conn) {
return this.errorNoConnection();
}
const data = yield conn.api.getManagedObjectData(iid);
if (!data) {
delete this.inventoryStubHunts[iid];
return resolve(false);
}
if (stubLock) {
this.lockStubs();
}
if (!moTypeClass) {
moTypeClass = (0, managed_objects_1.getMoTypeByName)((0, soap_parser_1.ref)(iid).attributes.type);
}
const mo = new moTypeClass(this, data);
if (stubLock) {
this.unlockStubs();
}
delete this.inventoryStubHunts[iid];
resolve(false);
}
catch (e) {
if (ignoreError) {
resolve(false);
}
this.ix.pushError(e);
}
}));
return this.inventoryStubHunts[iid];
});
}
get(iid, moTypeClass) {
return __awaiter(this, void 0, void 0, function* () {
iid = (0, managed_objects_1.iidParse)(iid);
if (this.inventory.byIID[iid]) {
return this.inventory.byIID[iid];
}
let mo = null;
const moResolver = this.fetchNewMo(iid, moTypeClass);
yield Promise.resolve(moResolver);
mo = this.inventory.byIID[iid];
if (!mo) {
return null;
}
return mo;
});
}
getMany(iids) {
return __awaiter(this, void 0, void 0, function* () {
const newMos = [];
const allProms = [];
this.lockStubs();
for (let iid of iids) {
iid = (0, managed_objects_1.iidParse)(iid);
if (this.inventory.byIID[iid]) {
newMos.push(this.inventory.byIID[iid]);
continue;
}
const moResolver = this.fetchNewMo(iid, (0, managed_objects_1.getMoTypeByName)((0, soap_parser_1.ref)(iid).attributes.type), false, true);
allProms.push(moResolver);
}
yield Promise.all(allProms);
this.unlockStubs();
return newMos;
});
}
getByName(name) {
const list = this.index.byName[name];
if (!list || !list[0]) {
return null;
}
return this.inventory.byIID[list[0]];
}
getManyByName(name) {
const list = this.index.byName[name];
return list ? list : [];
}
updateInventoryInterval(seconds) {
this.inventoryCheckInterval = seconds;
if (this.inventoryCheckInterval < 5) {
this.inventoryCheckInterval = 5;
}
return this.inventoryCheckInterval;
}
startInventoryWatch(checkIntervalSeconds = 10) {
this.updateInventoryInterval(checkIntervalSeconds);
if (this.inventoryWatchStarted) {
return;
}
this.inventoryWatchStarted = true;
const checker = () => __awaiter(this, void 0, void 0, function* () {
if (this.destroyed) {
return;
}
if (!this.inventoryWatchStarted) {
return;
}
if (this.ix.reconn.defunctState) {
return;
}
if (Date.now() - this.inventoryCheckLast > this.inventoryCheckInterval * 1000) {
const pendingKeys = Object.keys(this.inventoryStubHunts);
if (pendingKeys.length > 0) {
const proms = [];
for (const pendingKey of pendingKeys) {
proms.push(this.inventoryStubHunts[pendingKey]);
}
yield ts_basis_1.PromUtil.allSettled(proms);
}
this.inventoryCheckLast = Date.now();
try {
this.checkInventory();
}
catch (e) {
this.ix.pushError(e);
}
}
});
ts_basis_1.Tasks.addForeground(this, `inventory-watch`, checker, 1000);
}
stopInventoryWatch() {
if (!this.inventoryWatchStarted) {
return;
}
this.inventoryWatchStarted = false;
this.inventoryWatchChecker.destroy();
this.inventoryWatchChecker = null;
}
refreshComputeResourceInfo() {
return __awaiter(this, void 0, void 0, function* () {
const allProms = [];
for (const clusterId of Object.keys(this.inventory.computeResource)) {
allProms.push(this.inventory.computeResource[clusterId].refresh());
break;
}
for (const hostId of Object.keys(this.inventory.hostSystem)) {
allProms.push(this.inventory.hostSystem[hostId].refresh());
}
const results = yield ts_basis_1.PromUtil.allSettled(allProms);
return results.filter(r => r).length === results.length;
});
}
recalculateUtilization(noRefresh = false) {
return __awaiter(this, void 0, void 0, function* () {
if (!noRefresh) {
const refreshAllSuccess = yield this.refreshComputeResourceInfo();
if (!refreshAllSuccess) {
return null;
}
}
const hostCount = Object.keys(this.inventory.hostSystem).length;
const vmCount = Object.keys(this.inventory.virtualMachine).length;
const u9n = {
t: Date.now(), hostCount, vmCount,
percent: { cpu: 0, mem: 0, disk: 0 },
overview: {
totalCpu: 0, consumedCpu: 0, percentCpu: 0,
totalMem: 0, consumedMem: 0, percentMem: 0,
totalStorage: 0, consumedStorage: 0, percentStorage: 0,
},
clusterSummary: null,
hostStats: [],
storageStats: [],
history: this.u9nWithHistory ? this.u9nHistory : null
};
for (const hostId of Object.keys(this.inventory.hostSystem)) {
const host = this.inventory.hostSystem[hostId];
if (!host || !host.summary) {
continue;
}
const hw = host.summary.hardware;
u9n.overview.totalCpu += hw.cpuMhz * hw.numCpuCores / 1000;
u9n.overview.totalMem += parseInt(hw.memorySize, 10) / ts_basis_1.Unit.GiB;
if (host.summary.quickStats) {
u9n.overview.consumedCpu += host.summary.quickStats.overallCpuUsage / 1000;
u9n.overview.consumedMem += host.summary.quickStats.overallMemoryUsage / 1024;
}
u9n.hostStats.push({ iid: hostId, name: host.name, networksCount: host.network.length, stats: host.summary.quickStats });
}
for (const dsId of Object.keys(this.inventory.datastore)) {
const ds = this.inventory.datastore[dsId];
if (!ds || !ds.info) {
continue;
}
if (ds.info.containerId === ds.info.aliasOf) {
const capBytes = parseInt(ds.summary.capacity, 10);
const freeBytes = parseInt(ds.summary.freeSpace, 10);
const usedBytes = capBytes - freeBytes;
u9n.overview.totalStorage += capBytes / ts_basis_1.Unit.GiB;
u9n.overview.consumedStorage += usedBytes / ts_basis_1.Unit.GiB;
}
u9n.storageStats.push({ iid: dsId, name: ds.name, info: ds.info, summary: ds.summary });
}
let cpuPercent = u9n.overview.consumedCpu / u9n.overview.totalCpu * 100;
if (isNaN(cpuPercent)) {
cpuPercent = 0;
}
let memPercent = u9n.overview.consumedMem / u9n.overview.totalMem * 100;
if (isNaN(memPercent)) {
memPercent = 0;
}
let diskPercent = u9n.overview.consumedStorage / u9n.overview.totalStorage * 100;
if (isNaN(diskPercent)) {
diskPercent = 0;
}
u9n.percent.cpu = u9n.overview.percentCpu = cpuPercent;
u9n.percent.mem = u9n.overview.percentMem = memPercent;
u9n.percent.disk = u9n.overview.percentStorage = diskPercent;
const snapshot = [
Math.floor(Date.now() / 1000) % 2592000,
u9n.hostCount,
u9n.vmCount,
parseFloat(numFormat(u9n.percent.cpu)),
parseFloat(numFormat(u9n.percent.mem)),
parseFloat(numFormat(u9n.percent.disk)),
];
if (snapshot[3] === null || snapshot[4] === null || snapshot[5] === null) {
this.ix.pushError(new Error(`utilization snapshot has null values`), 2);
return null;
}
this.u9nHistory.push(snapshot);
if (this.u9nHistory.length > this.u9nHistoryMaxKept) {
this.u9nHistory.shift();
}
this.utilization = u9n;
this.u9nSerialized = JSON.stringify(u9n);
this.emitEvent(this.u9nUpdate$, u9n);
return u9n;
});
}
updateU9nCheckInterval(seconds) {
this.u9nCheckInterval = seconds;
if (this.u9nCheckInterval < 5) {
this.u9nCheckInterval = 5;
}
return this.u9nCheckInterval;
}
startUtilizationWatch(checkIntervalSeconds = 60) {
this.updateU9nCheckInterval(checkIntervalSeconds);
if (this.u9nWatchStarted) {
return;
}
this.u9nWatchStarted = true;
const checker = () => __awaiter(this, void 0, void 0, function* () {
if (this.destroyed) {
return;
}
if (!this.u9nWatchStarted) {
return;
}
if (this.ix.reconn.defunctState) {
return;
}
if (Date.now() - this.u9nCheckLast > this.u9nCheckInterval * 1000) {
this.u9nCheckLast = Date.now();
let u9nResult;
try {
u9nResult = this.recalculateUtilization();
}
catch (e) {
this.ix.pushError(e);
}
if (!u9nResult) {
this.ix.pushError(new Error(`utilization calculation has errors`), 2);
}
}
});
ts_basis_1.Tasks.addForeground(this, 'utilization-watch', checker, 1000);
}
stopUtilizationWatch() {
if (!this.u9nWatchStarted) {
return;
}
this.u9nWatchStarted = false;
this.u9nWatchChecker.destroy();
this.u9nWatchChecker = null;
}
errorNoConnection(resolve) {
this.ix.pushError(new Error(`vCenter '${this.key}' has no usable connections`), 2);
if (resolve) {
resolve(null);
}
return null;
}
emitEvent(obs, eventData) {
var _a;
const rxObj = this.rx(null, { findNameFromThisObservable: obs });
if (!rxObj) {
this.debugOutput('Unrecognized event type from: ' + new Error('').stack);
return false;
}
const eventType = rxObj.name;
if (!eventData) {
eventData = {};
}
const sourceMo = eventData.target && eventData.target instanceof managed_objects_1.Mo.Base ? eventData.target : null;
const e = {
eventTime: Date.now(),
eventType,
sourceKey: this.key,
data: eventData,
moData: sourceMo ? sourceMo.$src : null,
};
rxObj.next(e);
if (eventType !== 'datacenter_generic') {
(_a = this.rx('datacenter_generic')) === null || _a === void 0 ? void 0 : _a.next(e);
}
for (const hook of this.webhooks) {
if (!hook.events) {
continue;
}
let matched = false;
if (hook.events.all || hook.events[eventType]) {
matched = true;
}
else {
const eventMatchers = Object.keys(hook.events);
for (const eventMatcher of eventMatchers) {
if (eventType.startsWith(eventMatcher)) {
matched = true;
break;
}
}
}
if (!matched) {
continue;
}
const postObj = { headers: null };
if (hook.headers) {
postObj.headers = hook.headers;
}
if (hook.data) {
e.extra = hook.data;
}
try {
axios_1.default.post(hook.url, e, postObj).then(_ => { }).catch(_ => { });
}
catch (e) {
this.debugOutput(e);
}
}
return true;
}
debugOutput(message, keepOnly = false) {
if (this.verbose) {
if (this.jsonLogs) {
if (message instanceof Error) {
const d = { t: Date.now(), src: this.ix.base, key: this.key, msg: `${message.stack ? message.stack : message.message}` };
if (keepOnly) {
VsphereDatacenter.keptData.push({ type: 'error', data: d });
}
else {
console.log(JSON.stringify(d));
}
}
else {
const d = { t: Date.now(), src: this.ix.base, key: this.key, msg: `${message}` };
if (keepOnly) {
VsphereDatacenter.keptData.push({ type: 'error', data: d });
}
else {
console.log(JSON.stringify(d));
}
}
}
else {
const date = new Date();
const dateStr = date.toISOString();
const locTime = localTime(date);
if (message instanceof Error) {
const d = `[${dateStr}] [${locTime}] [${this.ix.base}] [${this.key}] :: ${message.stack ? message.stack : message.message}`;
if (keepOnly) {
VsphereDatacenter.keptData.push({ type: 'message', data: d });
}
else {
console.log(d);
}
}
else {
const d = `[${dateStr}] [${locTime}] [${this.ix.base}] [${this.key}] :: ${message}`;
if (keepOnly) {
VsphereDatacenter.keptData.push({ type: 'message', data: d });
}
else {
console.log(d);
}
}
}
}
}
debugKeep(message) { this.debugOutput(message, true); }
readyResetState() {
this.ready = false;
if (!this.readyResolver) {
this.readyPromise = new Promise(resolve => this.readyResolver = resolve);
}
}
readyFulfill(value) {
if (this.readyResolver) {
this.readyResolver(value);
this.readyResolver = null;
}
}
}
exports.VsphereDatacenter = VsphereDatacenter;
VsphereDatacenter.keptData = [];
VsphereDatacenter.registry = {};
function localTime(date) {
let hours = date.getHours();
const minutes = date.getMinutes();
const ampm = hours >= 12 ? 'PM' : 'AM';
hours = hours % 12;
hours = hours ? hours : 12;
const hourStr = hours < 10 ? '0' + hours : hours;
const minuteStr = minutes < 10 ? '0' + minutes : minutes;
return hourStr + ':' + minuteStr + ' ' + ampm;
}
class VsphereInfra extends ts_basis_1.ix.Entity {
static grant() { VsphereInfra.granted = true; }
constructor(lcParent) {
super('vinfra');
this.datacenterData = {};
if (lcParent) {
lcParent.lifecycle.manage(this);
}
this.behavior = new VsphereBehaviorController(this);
}
getDatacenter(target) {
return (0, ts_basis_1.promise)((resolve) => __awaiter(this, void 0, void 0, function* () {
const vcenter = yield VsphereDatacenter.fromTargetInfo(target, this);
resolve(vcenter);
if (target.watch) {
try {
vcenter.startInventoryWatch();
vcenter.startUtilizationWatch();
}
catch (e) {
}
}
try {
yield vcenter.initializeConnection();
}
catch (e) {
vcenter.ix.pushError(e);
}
if (!target.skipFetch) {
try {
yield vcenter.getInventory();
yield vcenter.recalculateUtilization(true);
vcenter.u9nCheckLast = Date.now();
}
catch (e) {
vcenter.ix.pushError(e);
}
}
}));
}
}
exports.VsphereInfra = VsphereInfra;
VsphereInfra.granted = false;
class VsphereBehaviorController extends ts_basis_1.ix.Entity {
constructor(target) {
super('vinfra-controller');
this.verbose = false;
this.jsonLogs = false;
this.readonlyMode = false;
this.useSdkCache = true;
this.connection = {
timeout: 30
};
this.reconnect = new ts_basis_1.ix.ConfigSource(ts_basis_1.ix.ReconnEntityBehavior, { restoreCheckInterval: 300 });
this.webhooks = [];
this.target = target;
this.lifecycle.managedBy(target);
}
get dcMap() { return VsphereDatacenter.registry; }
setVerbose(value = true) {
value = value ? true : false;
this.verbose = value;
for (const key of Object.keys(this.dcMap)) {
this.dcMap[key].verbose = value;
}
}
setJsonLogs(value = true) {
value = value ? true : false;
this.jsonLogs = value;
for (const key of Object.keys(this.dcMap)) {
this.dcMap[key].jsonLogs = value;
}
}
setReadonlyMode(value = true) {
value = value ? true : false;
this.readonlyMode = value;
for (const key of Object.keys(this.dcMap)) {
this.dcMap[key].readonlyMode = value;
}
}
globallySetTlsUnchecked() { process.env.NODE_TLS_REJECT_UNAUTHORIZED = '0'; }
globallySetTlsChecked() { process.env.NODE_TLS_REJECT_UNAUTHORIZED = '1'; }
addWebhook(webhookDef) { this.webhooks.push(webhookDef); }
removeWebhook(webhookName) {
let i = -1;
for (const hook of this.webhooks) {
++i;
if (hook.name === webhookName) {
break;
}
}
if (i >= 0) {
this.webhooks.splice(i, 1);
}
}
}
exports.VsphereBehaviorController = VsphereBehaviorController;
function numFormat(n) {
if (n < 1) {
return n.toFixed(2);
}
else if (n < 10) {
return n.toFixed(1);
}
else {
return n.toFixed(0);
}
}
function retry(timeout, fn) {
return __awaiter(this, void 0, void 0, function* () {
return (0, ts_basis_1.promise)((resolve, reject) => __awaiter(this, void 0, void 0, function* () {
let finished = false;
fn().then(r => {
if (finished) {
return;
}
finished = true;
resolve(true);
}).catch(e => {
if (finished) {
return;
}
finished = true;
resolve(false);
});
setTimeout(() => {
if (finished) {
return;
}
finished = true;
resolve(false);
}, timeout * 1000);
}));
});
}
//# sourceMappingURL=vsphere.js.map