Name
global.VCenterVMsSensor
Description
Implementation of the VMWare - vCenter VMs sensor. Create VM records, create relationships between VMs and hosts, networks, folders and datastores. If the VM isn t in a folder, relate it to the datacenter. Trigger probes to get VM NICs.
Script
/* jshint -W030 */
var VCenterVMsSensor;
// DiscoveryCMPUtils won't be available if cloud management isn't active. Declaring
// this ensures that we won't get an exception when we check to see if it's active.
var DiscoveryCMPUtils;
(function() {
var vCenterSysId, vCenterUuid, datacenterMorId, datacenterSysId, _this, refreshOnly,esxSysId,
avoidIe, enableCmpApi,lookUpSysIds,
dsMap = { },
clusterDetails = [ ],
vmSchema = {
cmdb_ci_vmware_instance: {
index: [ [ 'object_id', 'vcenter_uuid' ], [ 'vm_instance_uuid', 'vcenter_uuid' ], [ 'vm_instance_uuid' ] ],
fixup: fixupVM,
preWrite: preWriteVm,
preWriteRels: preWriteVmRels,
parentOf: {
cmdb_ci_esx_server: 'Registered on::Has registered',
cmdb_ci_vcenter_network: 'Connected by::Connects',
cmdb_ci_vcenter_dvs: 'Connected by::Connects',
cmdb_ci_vcenter_dv_port_group: 'Connected by::Connects',
hostedOn: 'Hosted on::Hosts'
},
childOf: {
cmdb_ci_vcenter_datacenter: 'Contains::Contained by',
cmdb_ci_vcenter_folder: 'Contains::Contained by',
cmdb_ci_vcenter_datastore: 'Provides storage for::Stored on',
cmdb_ci_esx_resource_pool: 'Members::Member of'
}
}
},
args = {
schema: vmSchema
};
vmSchema.cmdb_ci_vmware_template = Object.create(vmSchema.cmdb_ci_vmware_instance);
VCenterVMsSensor = {
process: process,
type: "DiscoverySensor",
schema: vmSchema
};
if (typeof g_probe != 'undefined') {
refreshOnly = g_probe.getParameter('refresh_state') == 'true';
if (refreshOnly)
vmSchema.cmdb_ci_vmware_instance.preWrite = vmSchema.cmdb_ci_vmware_instance.preWriteRels = undefined;
}
/*
Sample data. Truncated for brevity, so possibly inconsistent:
{
"cmdb_ci_vmware_instance": [
{
"type": "VirtualMachine",
"morid": "vm-4373",
"name": "DC0_C1_RP2_VM11",
"cmdb_ci_vcenter_network": [
"dvportgroup-11"
],
"cmdb_ci_vcenter_datastore": [
"datastore-93"
],
"correlation_id": "42273e88-343c-9bda-96e1-9bd9680081f2",
"vm_instance_uuid": "5027ad3b-f66e-fe70-ab41-5d2dcdc52521",
"template": false,
"guest_id": "winNetStandardGuest",
"cpus": 1,
"memory": 64,
"cmdb_ci_esx_morid": "host-1078",
"state": "off",
"cmdb_ci_vcenter_folder": "group-v3",
"object_id": "vm-4373",
"image_path": "[SANLAB1GlobalDS_4] DC0_C1_RP2_VM11\/DC0_C1_RP2_VM11.vmx",
"disks": 1,
"disks_size": 0,
"nics": 1
}
],
"cmdb_ci_vmware_template": [
]
}
*/
//////////////////////////////////////////////////////////////////////////
function process(result) {
getProbeParms();
_this = this;
args.location = this.getLocationID();
args.statusId = new DiscoveryStatus(g_probe.getParameter('agent_correlator')+'');
args.mutexPrefix = datacenterMorId || esxSysId ;
if (esxSysId) {
lookUpSysIds = VMUtils.lookupSysIdsESX;
args.schema.cmdb_ci_vmware_instance.index = [[ 'object_id', 'vm_instance_uuid' ], [ 'vm_instance_uuid' ]]
}
else
lookUpSysIds = VMUtils.lookupSysIds;
// During normal discovery g_probe_parameters should always be defined.
// It's only undefined during test execution.
if (typeof g_probe_parameters != 'undefined') {
g_probe_parameters.cidata = this.getParameter('cidata');
g_probe_parameters.source = this.getParameter('source');
}
this.root = g_probe.getDocument().getDocumentElement();
this.statusID = new DiscoveryStatus(g_probe.getParameter('agent_correlator')+'');
output = JSON.parse(output);
args.results = output;
args.results = JsonCi.prepare(args);
VMUtils.triggerNextPage(_this, args.results.leftOverMors, [ 'disable_vm_nic_vnics', 'disable_vm_nic_vdisks', 'disable_vm_nic_probe', 'refresh_state', 'disable_vm_tags_probe' ]);
JsonCi.writeJsObject(args);
if (!esxSysId){
//adding hook to update the virtual_machine reference in cmdb_ci_drs_vm_config based on the vm_morid
var drsGlideRecord = new GlideRecord('cmdb_ci_drs_vm_config');
drsGlideRecord.addNullQuery('virtual_machine');
drsGlideRecord.query();
while (drsGlideRecord.next()) {
//safe check to make sure that the vm morid is not null
if (drsGlideRecord.object_id && drsGlideRecord.vcenter_ref) {
var vmSysId = VMUtils.lookupSysIds(drsGlideRecord.object_id.toString(), 'cmdb_ci_vmware_instance', drsGlideRecord.vcenter_ref);
drsGlideRecord.setValue('virtual_machine', vmSysId);
drsGlideRecord.update();
}
}
}
if (refreshOnly)
return;
// The CMP API requires that relationships from VM -> Datacenter be in place before
// it can identify a VM. In that case, it's not safe to trigger the NIC probe
// until relationships have been created.
if (!avoidIe && DiscoveryCMPUtils.isCmpActive()) {
JsonCi.updateRelationships(args);
try {
if (enableCmpApi)
DiscoveryCMPUtils.callCmpApi(args.results, vCenterUuid, datacenterMorId);
} catch (e) {
DiscoveryLogger.warn('Error when calling CM API: ' + (e.msg || e.toString()), 'VCenterVMsSensor', _this.getEccQueueId());
}
}
// Trigger probes configured to run after the VMs sensor.
if (esxSysId)
VMUtils.triggerProbes(_this, {
vm: args.results.cmdb_ci_vmware_instance
});
else
VMUtils.triggerProbes(_this, {
vm: args.results.cmdb_ci_vmware_instance,
template: args.results.cmdb_ci_vmware_template,
clusters: clusterDetails
});
// When CMP isn't active we trigger probes before creating relationships to make
// discovery faster
if (avoidIe || !DiscoveryCMPUtils.isCmpActive())
JsonCi.updateRelationships(args);
//update discovery_cloud_results if CMP plugin is not activated. The count gets added in other hook if cmp plugin is activated.
if (!enableCmpApi)
new CloudResourceDiscoveryCountHandler().saveCloudResourceCount(this.getAgentCorrelator(), 'cmdb_ci_vm_instance', args.results.cmdb_ci_vmware_instance.length);
//Delete if any duplicate VM record got created
args.results.cmdb_ci_vmware_instance.forEach(function(vm) {
var gr = new GlideRecord('cmdb_ci_vmware_instance');
gr.addQuery('object_id', vm.morid);
gr.addQuery('install_status','!=',7); // 7 is retired
gr.orderByDesc('sys_created_on');
gr.setLimit(2);
gr.query();
if (gr.getRowCount() > 1) {
gr.setLimit(1);
gr.deleteRecord();
}
});
}
//////////////////////////////////////////////////////////////////////////
function getProbeParms() {
vCenterSysId = (g_probe.getParameter('vcenter_sys_id') || '') + '';
vCenterUuid = (g_probe.getParameter('vcenter_uuid') || '') + '';
datacenterSysId = (g_probe.getParameter('datacenter_sys_id') || '') + '';
datacenterMorId = (g_probe.getParameter('datacenter_mor_id') || '') + '';
enableCmpApi = DiscoveryCMPUtils.isCmpActive() && (('' + g_probe.getParameter('enable_cmp_qa')) == 'true');
avoidIe = DiscoveryCMPUtils.isCmpActive() && (('' + g_probe.getParameter('avoid_id_engine')) != 'false');
esxSysId = (g_probe.getParameter('esx_sys_id') || '') + '';
}
//////////////////////////////////////////////////////////////////////////
function fixupVM(vm) {
if (vm.correlation_id) {
vm.bios_uuid = vm.correlation_id;
vm.correlation_id = VMUtils.turnUuidToCorrelationId(vm.correlation_id);
}
vm.vcenter_ref = vCenterSysId;
vm.vcenter_uuid = vCenterUuid;
vm.object_id = vm.morid;
vm.server = esxSysId;
buildClusterObject(vm.cmdb_ci_esx_morid);
}
//We need the list of cluster_ids to be passed to VMWarevCenterClusterDRSVMProbe which discovers DRS settings from vmware.
//We are fetching the VM's esx details based on which we are fetching the detail of the cluster.
function buildClusterObject(esxMorId) {
var esxId = esxSysId;
if (!esxId) {
var esxGR = new GlideRecord('cmdb_ci_esx_server');
if (esxGR.get('object_id', esxMorId))
esxId = esxGR.sys_id;
}
if (esxId) {
var relCIGR = new GlideRecord("cmdb_rel_ci");
relCIGR.addQuery('type.name', 'Members::Member of');
relCIGR.addQuery('child', esxId);
relCIGR.query();
while(relCIGR.next()){
var clusterMorId = relCIGR.parent.object_id;
//safe check to fetch the valid cluster_id if more than one record exists in the cmdb_rel_ci for the same esx & cluster
if (clusterMorId) {
clusterMorId = ''+clusterMorId;
var matchedIndex = clusterDetails.map(function(e) { return e.morid; }).indexOf(clusterMorId);
if (matchedIndex == -1) {
var clusterDetail = {};
clusterDetail.type = 'ClusterComputeResource';
clusterDetail.morid = clusterMorId;
clusterDetails.push(clusterDetail);
}
}
}
}
}
//////////////////////////////////////////////////////////////////////////
function preWriteVm(obj, gr) {
// '7' = retired, '1' == installed
// When a VM becomes stale we set the status to retired. We don't want
// to change the status unless we previously set it. The best we can do
// is to check to see if the status is what we would have set it to.
if (gr.install_status + '' == '7')
gr.install_status = '1';
try {
obj.cmdb_ci_esx_server = lookUpSysIds(obj.cmdb_ci_esx_morid, 'cmdb_ci_esx_server', (vCenterSysId ||esxSysId), 'morid');
gr = VmwareVmCorrelator.processVmInstanceOrTemplate(obj, obj.macs, obj.sys_class_name == 'cmdb_ci_vmware_template', addCiStuff, obj.cmdb_ci_esx_server, gr);
} catch (e) {
DiscoveryLogger.warn(e.msg || e.toString(), 'VCenterVMsSensor', _this.getEccQueueId());
return false;
}
obj.sys_id = '' + gr.sys_id;
JsonCi.discoveryPostWrite(obj, gr);
return false;
function addCiStuff(gr) {
JsonCi.discoveryPreWrite(obj, gr);
}
}
//////////////////////////////////////////////////////////////////////////
function preWriteVmRels(vm) {
// We tried to look up the esx server when writing the VM (so we could create the guest->ESX relationship.) The ESX
// server record may not have been created yet, so we'll try again here if we need to. If this happens we won't correlate
// guest->ESX in this sensor, even on rediscovery (because the guest_reconciled flag will be set.) That's OK because
// we'll do it in the ESX sensor (which will happen even during rediscovery).
if (!vm.cmdb_ci_esx_server)
vm.cmdb_ci_esx_server = lookUpSysIds(vm.cmdb_ci_esx_morid, 'cmdb_ci_esx_server', vCenterSysId || esxSysId, 'morid');
var networks = vm.cmdb_ci_vcenter_network;
vm.cmdb_ci_vcenter_network = lookUpSysIds(networks, 'cmdb_ci_vcenter_network', vCenterSysId || esxSysId);
vm.cmdb_ci_vcenter_dv_port_group = lookUpSysIds(networks, 'cmdb_ci_vcenter_dv_port_group', vCenterSysId || esxSysId);
vm.cmdb_ci_vcenter_dvs = lookUpSysIds(vm.cmdb_ci_vcenter_dvs, 'cmdb_ci_vcenter_dvs', vCenterSysId || esxSysId);
if (vm.cmdb_ci_esx_resource_pool)
vm.cmdb_ci_esx_resource_pool = lookUpSysIds(vm.cmdb_ci_esx_resource_pool, 'cmdb_ci_esx_resource_pool', vCenterSysId || esxSysId);
else if (vm.vapp)
vm.cmdb_ci_esx_resource_pool = lookUpSysIds(vm.vapp, 'cmdb_ci_esx_resource_pool', vCenterSysId || esxSysId);
vm.cmdb_ci_vcenter_folder = VMUtils.lookupSysIds(vm.cmdb_ci_vcenter_folder, 'cmdb_ci_vcenter_folder', vCenterSysId);
vm.cmdb_ci_vcenter_datastore = VMUtils.lookupSysIds(vm.cmdb_ci_vcenter_datastore, 'cmdb_ci_vcenter_datastore', vCenterSysId);
if (!vm.cmdb_ci_vcenter_folder && !vm.cmdb_ci_esx_resource_pool)
vm.cmdb_ci_vcenter_datacenter = datacenterSysId;
if (DiscoveryCMPUtils.isCmpActive())
vm.hostedOn = datacenterSysId;
}
})();
Sys ID
1c3194328f5b1200c2fe0b5437bdee21