Skip to content

Instantly share code, notes, and snippets.

@cmcdevitt
Created September 4, 2018 16:57
Show Gist options
  • Select an option

  • Save cmcdevitt/1ac4b78ff6c49ce9bf061be3be9644ec to your computer and use it in GitHub Desktop.

Select an option

Save cmcdevitt/1ac4b78ff6c49ce9bf061be3be9644ec to your computer and use it in GitHub Desktop.
A Business Rule on Application Software (with a List (u_depends_on) point to Application Software) to Add and Removes a CI Relationship.
/*
Business Rule
Name: relateToChildren
Table: Application Software [cmdb_ci_application_software]
When to Run: Before, Insert and Update
Filter Condition: u_depends_onVALCHANGES^EQ
BETA / Prototype / To-do: Code Clean up.
*/
(function executeRule(current, previous /*null when async*/) {
/*
if previous depends_on is undefined or null
then
take all new items and create a relationship (type: "Used by::Uses") in CI relationship table( cmdb_rel_ci) between this record an depends_on for each item
else if new item(s)
do above
else
remove relationship from items no longer in depends_on
In this prototype "parent" and "child" CI Class are the same: cmdb_ci_appliation_software
Notes:
(choice) connection_strength: "always"
(reference) type: "Used by::Uses" = '6afd799338a02000c18673032c71b87b'
(reference) parent: sys_id of parent
(reference) child: sys_id of child
current: sends everything that IS
previous: sends everythig that WAS
if current == previous then do nothing (both)
1. if previous not found in current then delete previous item (foreach previous compair agains all current) i.e. delete
if current not found in previous then add current item (foreach current item compair agains all previous) i.e. add
End Notes
*/
/*
//Returns a a string of sys_ids: in this case of the "children"
var listCurrent = current.u_depends_on.toString();
var arrCurrent = listCurrent.split(",");
for (var i=0; i < arrCurrent.length; i++) {
//gs.print("Reference value is: " + array[i]);
gs.log("CM Reference current value is: " + arrCurrent[i]);
}
//Returns a a string of sys_ids: in this case of the "children"
var listPrevious = previous.u_depends_on.toString();
var arrPrevious = listPrevious.split(",");
for (var ii=0; i < arrPrevious.length; ii++) {
//gs.print("Reference value is: " + array[i]);
gs.log("CM Reference previous value is: " + arrPrevious[ii]);
}
*/
//*****************************************************************************************************************************************
// work on finding diff between current and previous
// 1. Look for previous items not found in current items and delete the relationship
// The assumption is that if an Item IS in Previous ('was' state) and is NOT in Current ('is' state) then it was removed from this List.
var arrDeleteRel = [];
var listPrevious = previous.u_depends_on.toString();
var arrPrevious = listPrevious.split(",");
var matchFound = false; //Flag Assumes "No match"
for (var p=0; p < arrPrevious.length; p++) {
//gs.print("Reference value is: " + array[i]);
//gs.log("CM Outer, previous value is: " + arrPrevious[p]);
//Now loop through Current looking for missing items
var listCurrent = current.u_depends_on.toString();
var arrCurrent = listCurrent.split(",");
for (var c=0; c < arrCurrent.length; c++) {
//gs.print("Reference value is: " + array[i]);
//gs.log("CM current is: " + arrCurrent[c] + " previous is: " + arrPrevious[p] );
if(arrPrevious[p] == arrCurrent[c]){
//I found a match between Previous and Current, so these is nothing to do
matchFound = true;
}
}//End Loop through Current (Inner Loop)
if(matchFound == false){
//I did not find a single match between Previous and Current, so it was deleted from the List
arrDeleteRel.push(arrPrevious[p]);
}
//Reset matchFound flag for next outerloop iteration, in case there was an inner loop match
matchFound = false;
}//End Loop through Previous (OuterLoope)
//******* Test loop thrugh arrDeleteRel *****************
for (var t=0; t < arrDeleteRel.length; t++) {
//gs.print("Reference value is: " + array[i]);
gs.log("CM to Delete: " + arrDeleteRel[t]);
}
//******* End: Test loop thrugh arrDeleteRel
//*****************************************************************************************************************************************
// work on finding diff between current and previous
// 2. Look for current items not found in current items and add the relationship
// The assumption is that if an Item IS in Current ('is' state) and is NOT in Previous ('was' state) then it was added to the List.
var arrAddRel = [];
//var lstPrevious = previous.u_depends_on.toString();
var lstCurrent = current.u_depends_on.toString();
//var arrPreviousTwo = lstPrevious.split(",");
var arrCurrentTwo = lstCurrent.split(",");
var matchFoundTwo = false; //Flag Assumes "No match"
//for (var pp=0; pp < arrPreviousTwo.length; pp++) {
for (var cc=0; cc < arrCurrentTwo.length; cc++) {
//Now loop through Previous looking for missing items
//var lstCurrent = current.u_depends_on.toString();
var lstPrevious = previous.u_depends_on.toString();
//var arrCurrentTwo = lstCurrent.split(",");
var arrPreviousTwo = lstPrevious.split(",");
//for (var cc=0; cc < arrCurrentTwo.length; cc++) {
for (var pp=0; pp < arrPreviousTwo.length; pp++) {
if(arrPreviousTwo[pp] == arrCurrentTwo[cc]){
//I found a match between Previous and Current, so these is nothing to do
matchFoundTwo = true;
}
}//End Loop through Current (Inner Loop)
if(matchFoundTwo == false){
//I did not find a single match between Previous and Current, so it was deleted from the List
//arrAddRel.push(arrPreviousTwo[pp]);
arrAddRel.push(arrCurrentTwo[cc]);
}
//Reset matchFoundTwo flag for next outerloop iteration, in case there was an inner loop match
matchFoundTwo = false;
}//End Loop through Previous (OuterLoope)
//******* Test loop thrugh arrAddRel *********************
for (var tt=0; tt < arrAddRel.length; tt++) {
gs.log("CM to Add: " + arrAddRel[tt]);
}
//******* End: Test loop thrugh arrAddRel *****************
/*
//Add Relationships This section works
var TYPE = '6afd799338a02000c18673032c71b87b'; //"Used by::Uses"
var list = current.u_depends_on.toString();
var arrChildren = list.split(",");
for (var i=0; i < arrChildren.length; i++) {
var gr = new GlideRecord('cmdb_rel_ci');
gr.parent = current.sys_id;
gr.child = arrChildren[i];
gr.type = TYPE;
gr.connection_strength = 'always';
gr.update();
} //End for loop
//End: Add Relationships This section works
*/
if (arrDeleteRel.length >= 1){
updateCIRelationship('delete',arrDeleteRel,current.sys_id);
}
if (arrAddRel.length >= 1){
updateCIRelationship('add',arrAddRel,current.sys_id);
}
function updateCIRelationship(crud, toChange, parent ){
var TYPE = '6afd799338a02000c18673032c71b87b'; //"Used by::Uses" To-do move this to gs.getProperty()
var CON_STRENGTH = 'always'; //To-do move this to gs.getProperty()
var gr = '';
//crud :'add'|'delete'
//toChange : array of sys_id of the "children" / u_depends_on (list from Current & Previous)
//parent : sys_id of the "parent" / current.sys_id;
if (crud === 'add'){
for (var i=0; i < toChange.length; i++) {
gr = new GlideRecord('cmdb_rel_ci');
gr.parent = parent;
gr.child = toChange[i];
gr.type = TYPE;
gr.connection_strength = CON_STRENGTH;
gr.update();
gr = null;
} //End for loop
}else if (crud === 'delete'){
// Add delete query here
for (var d=0; d < toChange.length; d++) {
gr = new GlideRecord('cmdb_rel_ci');
//gr.parent = parent;
gr.addQuery('parent', '=', parent);
//gr.child = toChange[i];
gr.addQuery('child', '=',toChange[d]);
//gr.type = TYPE;
gr.addQuery('type', '=',TYPE);
//gr.connection_strength = CON_STRENGTH;
gr.addQuery('connection_strength', '=',CON_STRENGTH);
gr.query();
while(gr.next()){
gr.deleteRecord();
}
gr = null;
} //End for loop
}else{
// log wrong thing sent in crud
}//End if
}
})(current, previous);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment