UNPKG

vsphere-infra

Version:

891 lines (870 loc) 34 kB
/* * Copyright 2014-2021 Firestack, all rights reserved. */ import { Class, ix, PromUtil } from 'ts-basis'; import { MoBaseDetails, Permission } from '../../models/mo/mo.general'; import * as FolderTypes from '../../models/mo/mo.folder.models'; import * as ClusterTypes from '../../models/mo/mo.cluster.models'; import * as HostTypes from '../../models/mo/mo.host.models'; import * as DatastoreTypes from '../../models/mo/mo.datastore.models'; import * as NetworkTypes from '../../models/mo/mo.network.models'; import * as RespoolTypes from '../../models/mo/mo.respool.models'; import * as VMTypes from '../../models/mo/mo.vm.models'; import * as VSwitchTypes from '../../models/mo/mo.vswitch.models'; import { moref, PartialAny } from '../../models/mo.props'; import { VsphereDatacenter } from './vsphere'; export namespace Mo { export class Base extends ix.Entity implements MoBaseDetails<Mo.Base> { $dc: VsphereDatacenter = null; $type = 'Base'; $dirty = false; $initPending: boolean | Promise<boolean> = true; $defunct = false; $guid: string = null; $srcBefore: any = null; $src: any = null; $deletedTime: number = 0; $lastSync: number = 0; $syncing: Promise<boolean> = null; iid: moref = ''; name: string = ''; parent: Mo.Base = null; overallStatus: string; headers: { [header: string]: string} = {}; constructor($dc: VsphereDatacenter, init: any, preinit?: (thisRef: Mo.Base) => any) { super('ManagedObject', '$guid:' + $dc.key + ':' + init.iid); $dc.lifecycle.manage(this); if (preinit) { preinit(this); } this.$dc = $dc; this.$guid = '$guid:' + $dc.key + ':' + init.iid; this.iid = init.iid; this.$dc.inventory.byGUID[this.$guid] = this; this.$dc.inventory.byIID[this.iid] = this; this.updateFrom(init, true); this.$dc.emitEvent(this.$dc.entryRegister$, { target: this }); } async updateFrom(init: any, fromBase = false) { this.$srcBefore = this.$src; this.$src = init; this.setName(init); if (fromBase) { this.overallStatus = init.overallStatus ? init.overallStatus : ''; this.$lastSync = Date.now(); } await this.updateFromExtended(init); this.$dc.emitEvent(this.$dc.entryRefresh$, { target: this }); if (this.$src?.parent !== this.$srcBefore?.parent) { this.$dc.emitEvent(this.$dc.entryMove$, { target: this, from: this.$srcBefore?.parent, to: this.$src?.parent }); } return this; } async updateFromExtended(_: any): Promise<any> {} unregister() { if (this.$defunct) { return; } this.$defunct = true; this.$deletedTime = Date.now(); this.$dc.inventory.deleted.push(this); delete this.$dc.inventory.byGUID[this.$guid]; delete this.$dc.inventory.byIID[this.iid]; this.unregisterExtended(); this.unsetName(); } unregisterExtended() {} setName(init: any) { if (!init.name) { if (this instanceof Mo.ResourcePool) { init.name = init.summary.name; } else { init.name = this.iid.split(':').pop(); this.$dc.debugOutput(`Cannot resolve entity name of ${this.iid}, using ${init.name} instead.`); } } if (init.name.indexOf('|') > 0) { init.name = init.name.replace(/\|/g, '%7C'); } if (this.name !== init.name) { this.unsetName(); this.name = init.name; if (!this.$dc.index.byName[this.name]) { this.$dc.index.byName[this.name] = []; } this.$dc.index.byName[this.name].push(this.iid); } } unsetName(name?: string) { if (!name) { name = this.name; } if (!name) { return; } const nameReg = this.$dc.index.byName[name]; if (nameReg) { const nameIdx = nameReg.indexOf(this.iid); if (nameIdx >= 0) { nameReg.splice(nameIdx, 1); } if (nameReg.length === 0) { delete this.$dc.index.byName[name]; } } } getSourceData() { return this.$src; } getSourceDataBefore() { return this.$srcBefore; } toString() { return this.$guid; } toJSON() { return this.$guid; } entitySummaryHeaders() { return this.$guid + '|' + this.name + '|' + (this.parent ? this.parent.$guid : '') + '|' + this.getSerializedHeaders(); } getSerializedHeaders() { const kvPairs: string[] = []; for (const header of Object.keys(this.headers)) { const value = encodeURIComponent(this.headers[header]); kvPairs.push(`${header}=${value}`); } return kvPairs.join('&'); } moBaseSerializable() { return { $guid: this.$guid, $type: this.$type, $deletedTime: this.$deletedTime, $lastSync: this.$lastSync, iid: this.iid, name: this.name, parent: this.parent, overallStatus: this.overallStatus, }; } serialize() { return JSON.stringify({ ...this.moBaseSerializable() }); } refresh(): Promise<boolean> { if (this.$syncing) { return this.$syncing; } return this.$syncing = new Promise<boolean>(async resolve => { try { const conn = this.$dc.pickConnection(); if (!conn) { return this.$dc.errorNoConnection(resolve); } const data = await conn.api.getManagedObjectData(this.iid); if (data) { await this.updateFrom(data); } this.$syncing = null; resolve(data !== null); } catch (e) { this.$dc.ix.pushError(e); resolve(null); } }); } } export class Folder extends Mo.Base implements FolderTypes.FolderFullDetails<Mo.Base, Mo.Base> { childEntity: Mo.Base[] = []; constructor($dc: VsphereDatacenter, init: PartialAny<Mo.Folder>) { super($dc, init, this2 => this2.$type = 'Folder'); $dc.inventory.folder[this.iid] = this; this.updateFrom(init); } async updateFromExtended(init: PartialAny<Mo.Folder>) { return this.$initPending = new Promise<boolean>(async resolve => { const $dc = this.$dc; try { await Promise.resolve($dc.inventoryStubPending); const proms = []; this.childEntity.length = 0; if (init.childEntity) { for (const iid of init.childEntity) { findMo($dc, iid, Mo.Base, mo => this.childEntity.push(mo), proms); } } findMo($dc, init.parent, Mo.Base, mo => this.parent = mo, proms); await PromUtil.allSettled(proms); } catch (e) { this.$dc.debugOutput(e); } this.$initPending = false; resolve(false); }); } unregisterExtended() { delete this.$dc.inventory.folder[this.iid]; } moFolderSerializable() { return { childEntity: this.childEntity, }; } serialize() { return JSON.stringify({ ...this.moBaseSerializable(), ...this.moFolderSerializable(), }); } } export class ComputeResource extends Mo.Base implements ClusterTypes.ClusterFullDetails<Mo.Base, Mo.HostSystem, Mo.Datastore, Mo.Network, Mo.ResourcePool> { configurationEx: any; datastore: Mo.Datastore[] = []; datastoreSummary: DatastoreTypes.DatastoreSummary[] = []; drsFault: any; drsRecommendation: any; host: Mo.HostSystem[] = []; lifecycleManaged: boolean; migrationHistory: any; network: Mo.Network[] = []; recommendation: any; resourcePool: Mo.ResourcePool; summary: ClusterTypes.ClusterComputeResourceSummary; constructor($dc: VsphereDatacenter, init: PartialAny<Mo.ComputeResource>) { super($dc, init, this2 => this2.$type = 'ComputeResource'); $dc.inventory.computeResource[this.iid] = this; this.updateFrom(init); } async updateFromExtended(init: PartialAny<Mo.ComputeResource>) { return this.$initPending = new Promise<boolean>(async resolve => { const $dc = this.$dc; try { await Promise.resolve($dc.inventoryStubPending); const proms = []; this.host.length = 0; this.datastore.length = 0; this.datastoreSummary.length = 0; this.network.length = 0; if (init.host) { for (const iid of init.host) { findMo($dc, iid, Mo.HostSystem, mo => this.host.push(mo), proms); } } if (init.datastore) { for (const iid of init.datastore) { findMo($dc, iid, Mo.Datastore, mo => { this.datastoreSummary.push(mo.summary); this.datastore.push(mo); }, proms); } } if (init.network) { for (const iid of init.network) { findMo($dc, iid, Mo.Network, mo => this.network.push(mo), proms); } } this.configurationEx = init.configurationEx; this.drsFault = init.drsFault; this.drsRecommendation = init.drsRecommendation; this.lifecycleManaged = init.lifecycleManaged; this.migrationHistory = init.migrationHistory; this.recommendation = init.recommendation; this.summary = init.summary; findMo($dc, init.resourcePool, Mo.ResourcePool, mo => this.resourcePool = mo, proms); findMo($dc, init.parent, Mo.Base, mo => this.parent = mo, proms); await PromUtil.allSettled(proms); } catch (e) { this.$dc.debugOutput(e); } this.$initPending = false; resolve(false); }); } unregisterExtended() { delete this.$dc.inventory.computeResource[this.iid]; } moComputeResourceSerializable() { return { configurationEx: this.configurationEx, datastore: this.datastore, datastoreSummary: this.datastoreSummary, drsFault: this.drsFault, drsRecommendation: this.drsRecommendation, host: this.host, lifecycleManaged: this.lifecycleManaged, migrationHistory: this.migrationHistory, network: this.network, recommendation: this.recommendation, resourcePool: this.resourcePool, summary: this.summary, }; } serialize() { return JSON.stringify({ ...this.moBaseSerializable(), ...this.moComputeResourceSerializable(), }); } } export class HostSystem extends Mo.Base implements HostTypes.HostFullDetails<Mo.Base, Mo.Datastore, Mo.Network, Mo.VirtualMachine> { capability: HostTypes.HostCapability; config: HostTypes.HostConfigInfo; configManager: HostTypes.HostConfigManager; datastore: Mo.Datastore[] = []; datastoreSummary: DatastoreTypes.DatastoreSummary[] = []; hardware: HostTypes.HostHardware; network: Mo.Network[] = []; licensableResource: HostTypes.HostLicensableResourceInfo; runtime: HostTypes.HostRuntimeInfo; summary: HostTypes.HostListSummary; systemResources: HostTypes.HostConfigResourceAllocTree; vm: Mo.VirtualMachine[] = []; constructor($dc: VsphereDatacenter, init: PartialAny<Mo.HostSystem>) { super($dc, init, this2 => this2.$type = 'HostSystem'); $dc.inventory.hostSystem[this.iid] = this; this.updateFrom(init); } async updateFromExtended(init: PartialAny<Mo.HostSystem>) { return this.$initPending = new Promise<boolean>(async resolve => { const $dc = this.$dc; try { await Promise.resolve($dc.inventoryStubPending); const proms = []; this.datastore.length = 0; this.datastoreSummary.length = 0; this.network.length = 0; this.vm.length = 0; if (init.datastore) { for (const iid of init.datastore) { findMo($dc, iid, Mo.Datastore, mo => { this.datastoreSummary.push(mo.summary); this.datastore.push(mo); }, proms); } } if (init.network) { for (const iid of init.network) { findMo($dc, iid, Mo.Network, mo => this.network.push(mo), proms); } } if (init.vm) { for (const iid of init.vm) { findMo($dc, iid, Mo.VirtualMachine, mo => this.vm.push(mo), proms); } } this.capability = init.capability; this.config = init.config; this.configManager = init.configManager; this.hardware = init.hardware; this.licensableResource = init.licensableResource; this.overallStatus = init.overallStatus; this.runtime = init.runtime; this.summary = init.summary; this.systemResources = init.systemResources; findMo($dc, init.parent, Mo.Base, mo => this.parent = mo, proms); await PromUtil.allSettled(proms); } catch (e) { this.$dc.debugOutput(e); } this.$initPending = false; resolve(false); }); } unregisterExtended() { delete this.$dc.inventory.hostSystem[this.iid]; } moHostSystemSerializable() { return { capability: this.capability, config: this.config, configManager: this.configManager, datastore: this.datastore, datastoreSummary: this.datastoreSummary, hardware: this.hardware, licensableResource: this.licensableResource, network: this.network, overallStatus: this.overallStatus, runtime: this.runtime, summary: this.summary, systemResources: this.systemResources, vm: this.vm, }; } serialize() { return JSON.stringify({ ...this.moBaseSerializable(), ...this.moHostSystemSerializable(), }); } } export class Datacenter extends Mo.Base { datastore: Mo.Datastore[] = []; datastoreFolder: Mo.Folder; hostFolder: Mo.Folder; network: Mo.Network[] = []; networkFolder: Mo.Folder; vmFolder: Mo.Folder; constructor($dc: VsphereDatacenter, init: PartialAny<Mo.Datacenter>) { super($dc, init, this2 => this2.$type = 'Datacenter'); $dc.inventory.datacenter[this.iid] = this; this.updateFrom(init); } async updateFromExtended(init: PartialAny<Mo.Datacenter>) { return this.$initPending = new Promise<boolean>(async resolve => { const $dc = this.$dc; try { await Promise.resolve($dc.inventoryStubPending); const proms = []; this.datastore.length = 0; this.network.length = 0; if (init.datastore) { for (const iid of init.datastore) { findMo($dc, iid, Mo.Datastore, mo => this.datastore.push(mo), proms); } } if (init.network) { for (const iid of init.network) { findMo($dc, iid, Mo.Network, mo => this.network.push(mo), proms); } } findMo($dc, init.datastoreFolder, Mo.Folder, mo => this.datastoreFolder = mo, proms); findMo($dc, init.hostFolder, Mo.Folder, mo => this.hostFolder = mo, proms); findMo($dc, init.networkFolder, Mo.Folder, mo => this.networkFolder = mo, proms); findMo($dc, init.vmFolder, Mo.Folder, mo => this.vmFolder = mo, proms); findMo($dc, init.parent, Mo.Base, mo => this.parent = mo, proms); await PromUtil.allSettled(proms); } catch (e) { this.$dc.debugOutput(e); } this.$initPending = false; resolve(false); }); } unregisterExtended() { delete this.$dc.inventory.datacenter[this.iid]; } moDatacenterSerializable() { return { datastore: this.datastore, datastoreFolder: this.datastoreFolder, hostFolder: this.hostFolder, network: this.network, networkFolder: this.networkFolder, vmFolder: this.vmFolder, }; } serialize() { return JSON.stringify({ ...this.moBaseSerializable(), ...this.moDatacenterSerializable(), }); } } export class Datastore extends Mo.Base implements DatastoreTypes.DatastoreFullDetails<Mo.Base, Mo.Datastore, Mo.VirtualMachine> { aliasOf: Mo.Datastore; aliases: Mo.Datastore[] = []; capability: DatastoreTypes.DatastoreCapability; browser: moref; host: DatastoreTypes.DatastoreHostMount[] = []; info: DatastoreTypes.VsanDatastoreInfo; iormConfiguration?: DatastoreTypes.StorageIORMInfo; summary: DatastoreTypes.DatastoreSummary; vm: Mo.VirtualMachine[] = []; constructor($dc: VsphereDatacenter, init: PartialAny<Mo.Datastore>) { super($dc, init, this2 => this2.$type = 'Datastore'); $dc.inventory.datastore[this.iid] = this; this.updateFrom(init); } async updateFromExtended(init: PartialAny<Mo.Datastore>) { return this.$initPending = new Promise<boolean>(async resolve => { const $dc = this.$dc; try { await Promise.resolve($dc.inventoryStubPending); const proms = []; this.host.length = 0; this.vm.length = 0; if (init.vm) { for (const iid of init.vm) { findMo($dc, iid, Mo.VirtualMachine, mo => this.vm.push(mo), proms); } } this.host = init.host; this.browser = init.browser; this.capability = init.capability; this.info = init.info; this.iormConfiguration = init.iormConfiguration; this.summary = init.summary; this.summary.isAlias = (this.info.containerId !== this.info.aliasOf); findMo($dc, init.parent, Mo.Base, mo => this.parent = mo, proms); await PromUtil.allSettled(proms); } catch (e) { this.$dc.debugOutput(e); } this.$initPending = false; resolve(false); }); } unregisterExtended() { delete this.$dc.inventory.datastore[this.iid]; } moDatastoreSerializable() { return { aliasOf: this.aliasOf, aliases: this.aliases, browser: this.browser, capability: this.capability, host: this.host, info: this.info, iormConfiguration: this.iormConfiguration, summary: this.summary, vm: this.vm, }; } serialize() { return JSON.stringify({ ...this.moBaseSerializable(), ...this.moDatastoreSerializable(), }); } } export class Network extends Mo.Base implements NetworkTypes.NetworkFullDetails<Mo.Base, Mo.HostSystem, Mo.VirtualMachine> { capability: {[featureName: string]: boolean} = {}; extraConfig: any; host: Mo.HostSystem[] = []; summary: NetworkTypes.NetworkSummary; vm: Mo.VirtualMachine[] = []; constructor($dc: VsphereDatacenter, init: PartialAny<Mo.Network>) { super($dc, init, this2 => this2.$type = 'Network'); $dc.inventory.network[this.iid] = this; this.updateFrom(init); } async updateFromExtended(init: PartialAny<Mo.Network>) { return this.$initPending = new Promise<boolean>(async resolve => { const $dc = this.$dc; try { await Promise.resolve($dc.inventoryStubPending); const proms = []; this.host.length = 0; this.vm.length = 0; if (init.host) { for (const iid of init.host) { findMo($dc, iid, Mo.HostSystem, mo => this.host.push(mo), proms); } } if (init.vm) { for (const iid of init.vm) { findMo($dc, iid, Mo.VirtualMachine, mo => this.vm.push(mo), proms); } } this.capability = init.capability; this.extraConfig = init.extraConfig; this.summary = init.summary; findMo($dc, init.parent, Mo.Base, mo => this.parent = mo, proms); await PromUtil.allSettled(proms); } catch (e) { this.$dc.debugOutput(e); } this.$initPending = false; resolve(false); }); } unregisterExtended() { delete this.$dc.inventory.network[this.iid]; } moNetworkSerializable() { return { capability: this.capability, extraConfig: this.extraConfig, host: this.host, summary: this.summary, vm: this.vm, }; } serialize() { return JSON.stringify({ ...this.moBaseSerializable(), ...this.moNetworkSerializable(), }); } } export class ResourcePool extends Mo.Base implements RespoolTypes.ResourcePoolFullDetails<Mo.Base, Mo.ComputeResource, Mo.VirtualMachine> { childConfiguration: RespoolTypes.ResourceConfigSpec[] = []; config: RespoolTypes.ResourceConfigSpec; owner: Mo.ComputeResource; resourcePool: Mo.ResourcePool[] = []; runtime: RespoolTypes.ResourcePoolRuntimeInfo; summary: RespoolTypes.ResourcePoolSummary; vm: Mo.VirtualMachine[] = []; constructor($dc: VsphereDatacenter, init: PartialAny<Mo.ResourcePool>, preinit?: (thisRef: Base) => any) { super($dc, init, preinit ? preinit : this2 => this2.$type = 'ResourcePool'); $dc.inventory.resourcePool[this.iid] = this; this.updateFrom(init); } async updateFromExtended(init: PartialAny<Mo.ResourcePool>) { return this.$initPending = new Promise<boolean>(async resolve => { try { const $dc = this.$dc; await Promise.resolve($dc.inventoryStubPending); const proms = []; this.resourcePool.length = 0; this.vm.length = 0; if (init.resourcePool) { for (const iid of init.resourcePool) { findMo($dc, iid, Mo.ResourcePool, mo => { mo.parent = this; this.resourcePool.push(mo) }, proms); } } if (init.vm) { for (const iid of init.vm) { findMo($dc, iid, Mo.VirtualMachine, mo => this.vm.push(mo), proms); } } this.childConfiguration = init.childConfiguration; this.config = init.config; this.runtime = init.runtime; this.summary = init.summary; findMo($dc, init.owner, Mo.ComputeResource, mo => this.owner = mo, proms); await PromUtil.allSettled(proms); } catch (e) { this.$dc.debugOutput(e); } this.$initPending = false; resolve(false); }); } unregisterExtended() { delete this.$dc.inventory.resourcePool[this.iid]; } moResourcePoolSerializable() { return { childConfiguration: this.childConfiguration, config: this.config, owner: this.owner, resourcePool: this.resourcePool, runtime: this.runtime, summary: this.summary, vm: this.vm, }; } serialize() { return JSON.stringify({ ...this.moBaseSerializable(), ...this.moResourcePoolSerializable(), }); } } export class VirtualApp extends Mo.ResourcePool { childConfiguration: any; config: any; datastore: Mo.Datastore[] = []; network: Mo.Network[] = []; owner: Mo.ComputeResource; parentFolder: Mo.Folder; parentVApp: Mo.VirtualApp; resourcePool: Mo.ResourcePool[] = []; runtime: any; summary: any; vAppConfig: any; vm: Mo.VirtualMachine[] = []; constructor($dc: VsphereDatacenter, init: PartialAny<Mo.VirtualApp>) { super($dc, init, this2 => this2.$type = 'VirtualApp'); $dc.inventory.virtualApp[this.iid] = this; this.updateFrom(init); } async updateFromExtended(init: PartialAny<Mo.VirtualApp>) { return this.$initPending = new Promise<boolean>(async resolve => { const $dc = this.$dc; try { await Promise.resolve($dc.inventoryStubPending); const proms = []; this.datastore.length = 0; this.network.length = 0; this.resourcePool.length = 0; this.vm.length = 0; if (init.datastore) { for (const iid of init.datastore) { findMo($dc, iid, Mo.Datastore, mo => this.datastore.push(mo), proms); } } if (init.network) { for (const iid of init.network) { findMo($dc, iid, Mo.Network, mo => this.network.push(mo), proms); } } if (init.resourcePool) { for (const iid of init.resourcePool) { findMo($dc, iid, Mo.ResourcePool, mo => { mo.parent = this; this.resourcePool.push(mo); }, proms); } } if (init.vm) { for (const iid of init.vm) { findMo($dc, iid, Mo.VirtualMachine, mo => this.vm.push(mo), proms); } } this.childConfiguration = init.childConfiguration; this.config = init.config; this.runtime = init.runtime; this.summary = init.summary; this.vAppConfig = init.vAppConfig; findMo($dc, init.parentFolder, Mo.Folder, mo => this.parentFolder = mo, proms); findMo($dc, init.parentVApp, Mo.VirtualApp, mo => this.parentVApp = mo, proms); findMo($dc, init.owner, Mo.ComputeResource, mo => this.owner = mo, proms); findMo($dc, init.parent, Mo.Base, mo => this.parent = mo, proms); await PromUtil.allSettled(proms); } catch (e) { this.$dc.debugOutput(e); } this.$initPending = false; resolve(false); }); } unregisterExtended() { delete this.$dc.inventory.virtualApp[this.iid]; } moVirtualAppSerializable() { return { childConfiguration: this.childConfiguration, config: this.config, datastore: this.datastore, network: this.network, owner: this.owner, parentFolder: this.parentFolder, parentVApp: this.parentVApp, resourcePool: this.resourcePool, runtime: this.runtime, summary: this.summary, vAppConfig: this.vAppConfig, vm: this.vm, }; } serialize() { return JSON.stringify({ ...this.moBaseSerializable(), ...this.moVirtualAppSerializable(), }); } } export class VirtualMachine extends Mo.Base implements VMTypes.VirtualMachineFullDetails<Mo.Base, Mo.Datastore, Mo.Network, Mo.ResourcePool> { $registeredIP: string; capability: VMTypes.VirtualMachineCapability; config: VMTypes.VirtualMachineConfig; datastore: Mo.Datastore[] = []; guest: VMTypes.GuestInfo; guestHeartbeatStatus: string; layout: VMTypes.VirtualMachineFileLayout; network: Mo.Network[] = []; resourceConfig: RespoolTypes.ResourceConfigSpec; resourcePool: Mo.ResourcePool; runtime: VMTypes.VirtualMachineRuntimeInfo; storage: VMTypes.VirtualMachineStorageInfo; summary: VMTypes.VirtualMachineSummary; constructor($dc: VsphereDatacenter, init: PartialAny<Mo.VirtualMachine>) { super($dc, init, this2 => { (this2 as VirtualMachine).$registeredIP = null; this2.$type = 'VirtualMachine'; }); $dc.inventory.virtualMachine[this.iid] = this; this.updateFrom(init); } async updateFromExtended(init: PartialAny<Mo.VirtualMachine>) { return this.$initPending = new Promise<boolean>(async resolve => { const $dc = this.$dc; try { await Promise.resolve($dc.inventoryStubPending); const proms = []; this.datastore.length = 0; this.network.length = 0; if (init.datastore) { for (const iid of init.datastore) { findMo($dc, iid, Mo.Datastore, mo => this.datastore.push(mo), proms); } } if (init.network) { for (const iid of init.network) { findMo($dc, iid, Mo.Network, mo => this.network.push(mo), proms); } } this.linkIP(init); this.capability = init.capability; this.config = init.config; this.guest = init.guest; this.guestHeartbeatStatus = init.guestHeartbeatStatus; this.layout = init.layout; this.resourceConfig = init.resourceConfig; this.runtime = init.runtime; this.storage = init.storage; this.summary = init.summary; findMo($dc, init.resourcePool, Mo.ResourcePool, mo => this.resourcePool = mo, proms); findMo($dc, init.parent, Mo.Base, mo => this.parent = mo, proms); await PromUtil.allSettled(proms); } catch (e) { this.$dc.debugOutput(e); } this.$initPending = false; resolve(false); }); } unregisterExtended() { delete this.$dc.inventory.virtualMachine[this.iid]; this.unlinkIP(); } linkIP(init: PartialAny<Mo.VirtualMachine>) { if (this.$registeredIP) { this.unlinkIP(); } if (init.guest?.ipAddress) { const ip = init.guest.ipAddress; if (!this.$dc.index.byIP[ip]) { this.$dc.index.byIP[ip] = []; } this.$dc.index.byIP[ip].push(this.iid); this.$registeredIP = ip; } } unlinkIP() { if (this.$registeredIP) { const ipReg = this.$dc.index.byIP[this.$registeredIP]; if (ipReg) { const ipIdx = ipReg.indexOf(this.iid); if (ipIdx >= 0) { ipReg.splice(ipIdx, 1); } if (ipReg.length === 0) { delete this.$dc.index.byIP[this.$registeredIP]; } } } } moVirtualMachineSerializable() { return { $registeredIP: this.$registeredIP, capability: this.capability, config: this.config, datastore: this.datastore, guest: this.guest, guestHeartbeatStatus: this.guestHeartbeatStatus, layout: this.layout, network: this.network, resourceConfig: this.resourceConfig, resourcePool: this.resourcePool, runtime: this.runtime, storage: this.storage, summary: this.summary, }; } serialize() { return JSON.stringify({ ...this.moBaseSerializable(), ...this.moVirtualMachineSerializable(), }); } } export class VirtualSwitch extends Mo.Base implements VSwitchTypes.VirtualSwitchFullDetails<Mo.Base, Mo.Network> { capability: VSwitchTypes.DVSCapability; config: VSwitchTypes.DVSConfigInfo; configStatus: string; permission: Permission[] = []; portgroup: Mo.Network[] = []; runtime: VSwitchTypes.DVSRuntimeInfo; summary: VSwitchTypes.DVSSummary; uuid: string; constructor($dc: VsphereDatacenter, init: PartialAny<Mo.VirtualSwitch>) { super($dc, init, this2 => this2.$type = 'VirtualSwitch'); $dc.inventory.virtualSwitch[this.iid] = this; this.updateFrom(init); } async updateFromExtended(init: PartialAny<Mo.VirtualSwitch>) { return this.$initPending = new Promise<boolean>(async resolve => { const $dc = this.$dc; try { await Promise.resolve($dc.inventoryStubPending); const proms = []; this.portgroup.length = 0; if (init.portgroup) { for (const iid of init.portgroup) { findMo($dc, iid, Mo.Network, mo => this.portgroup.push(mo), proms); } } this.capability = init.capability; this.config = init.config; this.configStatus = init.configStatus; this.permission = init.permission; this.runtime = init.runtime; this.summary = init.summary; this.uuid = init.uuid; findMo($dc, init.parent, Mo.Base, mo => this.parent = mo, proms); await PromUtil.allSettled(proms); } catch (e) { this.$dc.debugOutput(e); } this.$initPending = false; resolve(false); }); } unregisterExtended() { delete this.$dc.inventory.virtualSwitch[this.iid]; } moVirtualSwitchSerializable() { return { capability: this.capability, config: this.config, configStatus: this.configStatus, permission: this.permission, portgroup: this.portgroup, runtime: this.runtime, summary: this.summary, uuid: this.uuid, }; } serialize() { return JSON.stringify({ ...this.moBaseSerializable(), ...this.moVirtualSwitchSerializable(), }); } } } export function getMoTypeByName(moTypeName: string) { switch (moTypeName) { case 'Base': return Mo.Base; case 'Folder': return Mo.Folder; case 'HostSystem': return Mo.HostSystem; case 'Datacenter': return Mo.Datacenter; case 'Network': return Mo.Network; case 'Datastore': return Mo.Datastore; case 'ComputeResource': return Mo.ComputeResource; case 'ResourcePool': return Mo.ResourcePool; case 'VirtualApp': return Mo.VirtualApp; case 'VirtualMachine': return Mo.VirtualMachine; case 'DistributedVirtualPortgroup': return Mo.Network; case 'VirtualSwitch': case 'DistributedVirtualSwitch': case 'VmwareDistributedVirtualSwitch': return Mo.VirtualSwitch; default: console.log(`Unknown managed object type ${moTypeName}`); break; } return null; } export function iidParse(iid: string) { if (iid.startsWith('$mo:')) { return iid; } else { const valueLit = iid.split('-'); const valueType = valueLit[0]; const valueSubtype = valueLit[1]; switch (valueType) { case 'group': return `$mo:Folder:${iid}`; case 'datacenter': return `$mo:Datacenter:${iid}`; case 'network': case 'dvportgroup': return `$mo:Network:${iid}`; case 'datastore': return `$mo:Datastore:${iid}`; case 'domain': return `$mo:ComputeResource:${iid}`; case 'resgroup': if (valueSubtype.startsWith('v')) { return `$mo:VirtualApp:${iid}`; } else { return `$mo:ResourcePool:${iid}`; } case 'host': return `$mo:HostSystem:${iid}`; case 'vm': return `$mo:VirtualMachine:${iid}`; case 'dvs': return `$mo:VirtualSwitch:${iid}`; default: console.log(`Unknown mo value ${iid}`); return null; } } } export function findMo<T = any>($dc: VsphereDatacenter, iid: string, typeClass?: Class<T>, onresolve?: (mo: T) => any, proms?: Promise<any>[]) { const prom = new Promise<T>(async resolve => { let mo = $dc.inventory.byIID[iid] as any; if (!mo && iid) { $dc.debugKeep(`${iid} not found during linkage; fetching...`); mo = await $dc.get(iid, typeClass); $dc.debugKeep(`${iid} fetched`); } if (onresolve) { onresolve(mo); } return resolve(mo as T); }); if (proms) { proms.push(prom); } return prom; }