vsphere-infra
Version:
891 lines (870 loc) • 34 kB
text/typescript
/*
* 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;
}