Name

sn_cmp.CMPReconciler

Description

No description available

Script

var CMPReconciler = Class.create();
CMPReconciler.prototype = {
  initialize: function() {
  },
  
  reconcile : function(orderGrSysId) {
  	var orderGr = new GlideRecord('sn_cmp_order');
  	if (!orderGr.get(orderGrSysId))
  		return;
  	var ldcId = orderGr.getValue('owner_instance');
  	if (!ldcId)
  		return;
  	var LDCGr = this.getLDCGr(ldcId);
  	if (!LDCGr)
  		return;
  	
  	var orderDate = new GlideDateTime(orderGr.getValue('order_date'));
  	
  	var steps = new GlideRecord('sn_cmp_order_step_status');
  	steps.addQuery('order', orderGr.getUniqueValue());
  	steps.addQuery('status', '3'); //completed
  	steps.query();
  	while (steps.next()) {
  		var apiStep = global.JSON.parse(steps.getValue('api_step'));
  		if (!apiStep)
  			continue;
  		var capiInterface = apiStep.interfaceName;
  		var capiMethod = apiStep.methodName;
  		var stepGr = this.getDiscoveryStepGr(capiInterface, capiMethod);
  		if (!stepGr)
  			continue;
  		var resourceType = this.getResourceTypeFromStep(stepGr);
  		if (!resourceType)
  			continue;
  		this.reconcileCI(resourceType, ldcId, orderDate);
  	}
  },
  
  getLDCGr : function(ldcId) {
  	var LDCGr = new GlideRecord('cmdb_ci_logical_datacenter');
  	if (LDCGr.get(ldcId))
  		return LDCGr;
  	return null;
  },
  
  getDiscoveryStepGr : function(capiInterface, capiMethod) {
  	var stepGr = new GlideRecord('sn_cmp_rb_op_impl_step');
  	stepGr.addQuery('capi_interface.interface_name', capiInterface);
  	stepGr.addQuery('capi_method.operation_name', capiMethod);
  	stepGr.query();
  	if (stepGr.hasNext())
  		return stepGr;
  	return null;
  },
  
  getResourceTypeFromStep : function(stepGr) {
  	var discoStepMapping = new GlideRecord('sn_cmp_resource_type_operation');
  	while (stepGr.next()) {
  		if (discoStepMapping.get('discovery_step', stepGr.getUniqueValue()))
  			return discoStepMapping.resource_type;
  	}
  	return null;
  },
  
  reconcileCI : function(resourceType, ldcId, orderDate) {
  	var ciClass = resourceType.ci_class+'';
  	if (!ciClass)
  		return;
  	var ci = new GlideRecord(ciClass);
  	var rel = new GlideRecord('cmdb_rel_ci');
  	rel.addQuery('parent.operational_status','!=','2');
  	rel.addQuery('parent.sys_class_name', ciClass);
  	rel.addQuery('child', ldcId);
  	rel.addQuery('type.name', 'Hosted on::Hosts');
  	rel.query();
  	while (rel.next()) {
  		if(ci.get(rel.parent+'')) {
  			if (this.isCIStale(rel.parent, orderDate)) 
  				this.markCIAbsent(ci);
  			this.reconcileChildCIs(resourceType, ci, orderDate);		
  		}	
  	}
  	
  	var rel1 = new GlideRecord('cmdb_rel_ci');
  	rel1.addQuery('child.operational_status','!=','2');
  	rel1.addQuery('child.sys_class_name', ciClass);
  	rel1.addQuery('parent', ldcId);
  	rel1.addQuery('type.name', 'Contains::Contained by');
  	rel1.query();
  	while (rel1.next()) {
  		if(ci.get(rel1.child+'')) {
  			if (this.isCIStale(rel1.child, orderDate)) 
  				this.markCIAbsent(ci);
  			this.reconcileChildCIs(resourceType, ci, orderDate);					
  		}	
  	}
  },
  
  reconcileChildCIs : function(resourceType, parentCI, date) {
  	var childCIClass = this.getChildCIClass(resourceType);
  	if (!childCIClass)
  		return;
  	var childCIs = this.getChildCIs(parentCI, childCIClass);
  	
  	for (var index=0; index<childCIs.length; index++) {
  		var childCI = childCIs[index];
  		var ci = new GlideRecord(childCI.table);
  		if (ci.get(childCI.sysId)) {
  			if (this.isCIStale(ci, date))
  				this.markCIAbsent(ci);
  		}
  	}
  },
  
  getChildCIClass : function(resourceType) {
  	var childCIClass = [];
  	var rtMapping = new GlideRecord('sn_capi_rt_rel');
  	rtMapping.addQuery('parent', resourceType);
  	rtMapping.query();
  	while (rtMapping.next()) 
  		childCIClass.push(rtMapping.child.ci_class+'');	
  	return childCIClass;		
  },
  
  getChildCIs : function(ci, childCIClass) {
  	var childCIs = [];
  	var rel = new GlideRecord('cmdb_rel_ci');
  	rel.addQuery('parent', ci.getUniqueValue());
  	rel.addQuery('type.name', 'Contains::Contained by');
  	rel.addQuery('child.sys_class_name', 'IN', childCIClass);
  	rel.addQuery('child.operational_status', '!=', '2');//filter out already reconciled CIs
  	rel.query();
  	while (rel.next()) {
  		var childCI = {};
  		childCI.sysId = rel.getValue('child');
  		childCI.table = rel.child.sys_class_name+'';
  		childCIs.push(childCI);
  	}
  	return childCIs;
  },
  
  isCIStale : function(ci, date) {
  	var mostRecentDisco = new GlideDateTime(ci.last_discovered);
  	if (mostRecentDisco.before(date))
  		return true;
  	return false;
  },
  
  markCIAbsent : function(ci) {
  	if (!ci.isValidField('operational_status') || !ci.isValidField('install_status'))
  		return;
  	if (ci.isValidField('state'))
  		ci.state = 'terminated';
  	ci.operational_status = '2';//non-operational
  	ci.install_status = '100';//absent
  	ci.update();
  },
  
  retireCI : function(ci) {
  	if (!ci.isValidField('operational_status') || !ci.isValidField('install_status'))
  		return;
  	if (ci.isValidField('state'))
  		ci.state = 'terminated';
  	ci.operational_status = '6';//retired
  	ci.update();
  },
  
  markErroredCI : function(ci) {
  	if (!ci.isValidField('operational_status') || !ci.isValidField('install_status') || !ci.isValidField('state'))
  		return;

  	ci.operational_status = '2';//non-operational
  	ci.install_status = '100';//absent
  	ci.update();
  },

  reviveCI : function(ci) {
  	if (!ci.isValidField('operational_status') || !ci.isValidField('install_status'))
  		return;
  	ci.operational_status = '1';//operational
  	ci.install_status = '1';//installed
  	ci.update();
  },

  //retireCIbeforeUpdate(), markErroredCIbeforeUpdate(), reviveCIbeforeUpdate() are added to avoid performance issues seen if ci.update() is added in Business rules.
  //Please refer KB0715782 for more details.
  retireCIbeforeUpdate : function(ci) {
  	if (!ci.isValidField('operational_status') || !ci.isValidField('install_status'))
  		return;
  	if (ci.isValidField('state'))
  		ci.state = 'terminated';
  	ci.operational_status = '6';//retired
  	//ci.update() is not added as the call is from before BR which saves this update.
  },

  markErroredCIbeforeUpdate : function(ci) {
  	if (!ci.isValidField('operational_status') || !ci.isValidField('install_status') || !ci.isValidField('state'))
  		return;

  	ci.operational_status = '2';//non-operational
  	ci.install_status = '100';//absent
  	//ci.update() is not added as the call is from before BR which saves this update
  },

  reviveCIbeforeUpdate : function(ci) {
  	if (!ci.isValidField('operational_status') || !ci.isValidField('install_status'))
  		return;
  	ci.operational_status = '1';//operational
  	ci.install_status = '1';//installed
  	//ci.update() is not added as the call is from before BR which saves this update
  },

  type: 'CMPReconciler'
};

Sys ID

3d264e72d7a1320097eb6ccf6e61037f

Offical Documentation

Official Docs: