@stordata/vsphere-soapify
Version:
A NodeJS abstraction layer for the vSphere SOAP API
138 lines (119 loc) • 4.66 kB
JavaScript
/* eslint-disable no-param-reassign */
;
const _ = require('lodash'),
Instance = require('../Instance'),
PropertyFilterSpec = require('../data/PropertyFilterSpec'),
PropertySpec = require('../data/PropertySpec'),
ObjectSpec = require('../data/ObjectSpec'),
TraversalSpec = require('../data/TraversalSpec'),
AlarmState = require('../data/AlarmState');
module.exports = class ManagedEntity extends Instance {
constructor(client, ref, propSet = []) {
super(client);
this.ref = ref;
// Reduce the propSet array to properties of this managed object
this.fill(propSet.reduce((source, { name, val }) => _.set(source, name, val), {}));
}
/**
* Fetch full instances (including properties) of referenced entities.
* Internally uses the {@link PropertyCollector} to fetch the properties of the instances.
*
* @param property {String} The name of the property to fetch the instances for. MUST exist on this object
* @param [properties] An optional list of properties to fetch. By default, all properties are fetched
* @param [type] {Class} The type of the fetched instances. By default the library automatically detects the type
*
* @returns {Promise<Array<ManagedEntity>>} A Promise resolving with a list of {@link ManagedEntity} instances
*/
async getAll(property, properties, type) {
const value = this[property],
isArray = Array.isArray(value);
// Property is not defined, or is an empty array? Do not bother calling the collector
if (!value || (isArray && !value.length)) {
return [];
}
// Automatic type detection... Kind of :/
if (!type) {
type = (isArray ? value[0] : value).constructor;
}
return this.client.getPropertyCollector()
.then(collector => collector.retrievePropertiesEx(new PropertyFilterSpec(
new PropertySpec(type.name, false, properties || type.properties()),
new ObjectSpec(this, true, new TraversalSpec(this.constructor.name, property))
)));
}
/**
* Fetch a full instance (including properties) of a referenced entity.
* Internally delegates to {@link getAll} and return the first found instance.
*
* @param property {String} The name of the property to fetch the instance for
* @param [properties] An optional list of properties to fetch
* @param [type] {Class} The type of the fetched instance
*
* @returns {Promise<ManagedEntity>} A Promise resolving with a {@link ManagedEntity} instance
*
* @see getAll
*/
async get(property, properties, type) {
return this.getAll(property, properties, type).then(_.first);
}
/**
* Reloads this ManagedEntity instance with properties.
* Internally delegates to the {@link PropertyCollector} to retrieve the properties.
*
* @param [properties] {Array<String>} An optional list of properties to fetch. By default all properties are fetched
*
* @returns {Promise<ManagedEntity>} A Promise resolving with the entity, including fetched properties
*/
async withProperties(properties) {
return this.client.getPropertyCollector().then(collector => collector.retrieveObjectWithProperties(this, properties));
}
// Utility functions
toXmlObject() {
return {
attributes: {
type: this.constructor.name
},
$value: this.ref
};
}
/**
* Calls a method.
* Serialization is handled automatically (hopefully !) so you pass object instances directly
*
* @param method {String} The method to call
* @param [args] {Object} The arguments for the call
* @param [type] {Class} The return type of the call. When defined, the result is parsed to that SDK object
*
* @returns {Promise<Object>} A Promise resolving with the (optionally parsed) result of the call
*/
call(method, args, type) {
return this.client.getClient()
.then(client => client[method]({
_this: this.toXmlObject(),
...this.normalizeArgs(args)
}))
.then(([result]) => result && result.returnval)
.then((result) => {
if (!type) {
return result;
}
return this.parse(result, type);
});
}
normalizeArgs(args = {}) {
return Object.entries(args).reduce((object, [key, value]) => ({
...object,
[key]: this.xmlValue(value)
}), {});
}
static mappings() {
return {
name: 'xsd:string',
parent: 'ManagedObjectReference',
configStatus: 'ManagedEntityStatus',
overallStatus: 'ManagedEntityStatus',
alarmActionsEnabled: 'xsd:boolean',
triggeredAlarmState: AlarmState.ArrayOf
};
}
};