0% found this document useful (0 votes)
6 views32 pages

Its M Integration

The document outlines the ITSM Ticketing integration for Moogsoft, detailing how the Moobot monitors situations requiring tickets and manages ticket creation for support groups. It includes configuration settings, ticket creation scripts, and functions for adding work notes and configuration items (CIs) to tickets. The document emphasizes the proprietary nature of the source code and provides contact information for unauthorized access notifications.

Uploaded by

joedanie20
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as TXT, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
6 views32 pages

Its M Integration

The document outlines the ITSM Ticketing integration for Moogsoft, detailing how the Moobot monitors situations requiring tickets and manages ticket creation for support groups. It includes configuration settings, ticket creation scripts, and functions for adding work notes and configuration items (CIs) to tickets. The document emphasizes the proprietary nature of the source code and provides contact information for unauthorized access notifications.

Uploaded by

joedanie20
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as TXT, PDF, TXT or read online on Scribd
You are on page 1/ 32

/**************************************************************

* *
* Contents of file Copyright (c) Moogsoft Inc 2015 *
* *
*------------------------------------------------------------*
* *
* WARNING: *
* THIS FILE CONTAINS UNPUBLISHED PROPRIETARY *
* SOURCE CODE WHICH IS THE PROPERTY OF MOOGSOFT INC AND *
* WHOLLY OWNED SUBSIDIARY COMPANIES. *
* PLEASE READ THE FOLLOWING AND TAKE CAREFUL NOTE: *
* *
* This source code is confidential and any person who *
* receives a copy of it, or believes that they are viewing *
* it without permission is asked to notify Phil Tee *
* on 07734 591962 or email to phil@moogsoft.com. *
* All intellectual property rights in this source code *
* are owned by Moogsoft Inc. No part of this source *
* code may be reproduced, adapted or transmitted in any *
* form or by any means, electronic, mechanical, *
* photocopying, recording or otherwise. *
* *
* You have been warned....so be good for goodness sake... *
* *
**************************************************************/

/**
* Overview of how the ITSM Ticketing Works.
* This Moobot is essentially monitoring Situation custom_info for Support Groups
that need tickets.
* The Situation Manager Moobot looks at each alert that is added to the situation
to see if it requires
* a Ticket. If it does it checks to see if there is already a ticket for the
support group.
*
* A list of Support Groups that have or need tickets can be found at the key
* ITSM.groupsWithTickets
*
* A list of the current Ticket Numbers can be found using the key
* ITSM.IncidentNumbers
*
* Each Support Group will have its own branch under ITSM with the details needed
to create and maintain the ticket.
* ITSM[SupportGroupName]
*
* Configuration Information Stored in Config.Exxon.js under ITSMTicketing
* autoTicketCreate : true - Setting autoTicketCreate to true causes tickets to
be created from situations when there is a SupportGroup that requires a ticket
* nextMoolet : "TeamsMgr" - Name of next Moolet
* userName : "na\\xsmoogitsm" - User name to use for creating te ticket
* maxAlertDescriptionSize : 1024 - Max size of any alert description
* maxTotalAlertDescriptionSize : 4096 - Max size of alerts added to notes
* createTicketScript : "scripts/createTicket.sh" - Shell script to call when a
ticket is required.
* workNoteTicketScript : "script/workNoteTicket.sh" - Shell Script for adding
additional work notes to ticket
* addTicketCIScript : "scripts/RelShipTicket.sh" - Shell script for adding CIs
to Ticket
* addRelatedAlertsToNotes : true - When true all alerts for situation, but not
the support group, will have their description added to Ticket Notes
* addRelatedCIsToTicket : true - When true all host for alerts ath are not for
the same support group, will be added to the Ticket CIs
*
* @file ITSMIntegration.js
* @version 2.0
* @author Kirk Sievers kirk@moogsoft.com
*/

// load the minimum required

var events = MooBot.loadModule('Events');


var logger = MooBot.loadModule('Logger');
var constants = MooBot.loadModule('Constants');
var REST = MooBot.loadModule('REST.V2');
var moogdb = MooBot.loadModule('MoogDb.V2');
var process = MooBot.loadModule('Process');

/*
* For the ITSM integration for work properly there are a number of customer
specific
* properties that must be set.
*
* Most of them can be found here.
*
* The exception is that the fields that need to be populated when new ITSM requests
* are created must be defined in the situationNew() function
*/

// @requires exxon/MoobotUtils.Exxon.js */
MooBot.loadModule('exxon/MoobotUtils.Exxon.js');
var moobotUtils = new MoobotUtils();

// @requires exxon/Config.Exxon.js */
MooBot.loadModule('exxon/Config.Exxon.js');
var config = new Config();

// @requires exxon/MoobotUtils.Exxon.js */
MooBot.loadModule('BotUtility.js');
var botUtils = new BotUtility();

logger.info("Main Moobot ITSMIntegration START");

var DEBUG = true;

var ticketLineFeed = "\\n";

// Error Codes
// EITSM001 - This indicates that the situation does not have the custom_info
populated.
// This moolet may receive the Situation before SituaitonMgr has
finished processing and adding custom_info.
// You can ignor this as long as at soem point the ticket get created.

/**
* This function is called when the MooBot is first initialised in the farmd.
* Allows loading of required ServiceNow integration variables.
* The integration needs to be installed first. Only variables defined in
* properties section of the integration installation's def file will
* be available.
* @function onLoad
*/
function onLoad() {

/*
Ticket creation:

/script/createTicket.sh “$1” “$2” “$3” “$4” “$5” “$6” $7”

$1- Username (NA\xsmoogitsm)


$2 – Situation description
$3 – Notes (All Alert Description with Hostname)
$4 – Urgency
$5 – Service name
$6 – Assignment Group
$7 – Situation ID
$8 - Impact
Response will be : Incident Number or Error

Ticket worknotes:

/script/workNoteTicket.sh “$1” “$2”

$1 – Incident Number
$2 – Work Notes.

Response
Sample:
{“Worl_Log”:”WLG000005729906”,”Summary”:”test”,”Notes”:”test”,”Submitter”:”na\\
xsmoogitsm”,”Full Name”:”ITSM Moog”,”Submit_date”:”2017-08-
22T17:42:142Z”,”Last_Modified_Date”:” 2017-08-22T17:42:142Z”,”Type”:”General
Information”,”Entry_Locked”:false,”Attachments”:[]}

Add CI:
/scripts/RelShipTicket.sh “$1” “$2”

$1 = Incident Number
$2 = CI Information.

Response Code:

JSON or Error.

{"ID":"HAS000009336844","Name":"pnhemr03.ap.xom.com","Description":"pnhemr03.ap.xom
.com","Association":"Related to","Type":"Configuration
Item","Keyword":"BMC_COMPUTERSYSTEM","Is_Business_Service":false,"Status":"Deployed
","Dependents":[]}

*/

/**
* @function addWorkNote
* @param {string} incidentNumber
* @param {string} workNote
* @param {Object} [customInfo]
* @returns {boolean|Object} false if set to not add note or add note failed,
otherwise object containing the results
*/
function addWorkNote(incidentNumber, workNote, customInfo) {
var fn = "addWorkNote:: ";

if (config.ITSMTicketing.addRelatedAlertsToNotes === false) {


logger.warning(fn + "config.ITSMTicketing.addRelatedAlertsToNotes Set To
False. NOT Adding CI to Ticket.");
return false;
}
if (!incidentNumber || !workNote) {
logger.warning(fn + "Incident Number and Work Note were not passed. Could
not add work note");
return false;
}

logger.info(fn + "STARTING for Incident Number " + incidentNumber + "Worknote:


" + workNote);

var addWorkNoteProcess =
process.create(config.ITSMTicketing.workNoteTicketScript);

// noinspection SpellCheckingInspection
if (addWorkNoteProcess) {

// workNote = workNote.replace(/\n/g, " ").replace(/\r/g, "


").replace(/\\/g, "\\\\");
workNote = moobotUtils.itsmSafe(workNote);
/*
$1 – Incident Number
$2 – Work Notes.
*/

addWorkNoteProcess.arg(incidentNumber);
addWorkNoteProcess.arg(workNote);

var processResults = process.runToExit(addWorkNoteProcess);

// normal response will look like


//
{“Worl_Log”:”WLG000005729906”,”Summary”:”test”,”Notes”:”test”,”Submitter”:”na\\
xsmoogitsm”,”Full Name”:”ITSM Moog”,”Submit_date”:”2017-08-
22T17:42:142Z”,”Last_Modified_Date”:” 2017-08-22T17:42:142Z”,”Type”:”General
Information”,”Entry_Locked”:false,”Attachments”:[]}

logger.debug(fn + "Process Results: '" + processResults + "'");

var addWorkNoteProcessResults = addWorkNoteProcess.output();

if (!addWorkNoteProcessResults) {
logger.info(fn + "Bad results from addWorkNoteProcessResults -
returning false");
return false;
}

logger.info(fn + "Results from running the script: >>" +


addWorkNoteProcessResults + "<< ");
return addWorkNoteProcessResults;

else {
logger.warning(fn + "Process Object not created for " +
config.ITSMTicketing.workNoteTicketScript + "<< ");
return false;
}

/**
* This function will update the ticket with the related CIs.
* @function addCI
* @param {string} incidentNumber
* @param {string} ciName
* @param {Object} [customInfo]
* @returns {boolean|Object}
*/

function addCI(incidentNumber, ciName, customInfo) {


var fn = "addCI:: ";

if (config.ITSMTicketing.addRelatedCIsToTicket === false) {


logger.warning(fn + "config.ITSMTicketing.addRelatedCIsToTicket Set To
False. NOT Adding CI to Ticket.");
return false;
}

if (!incidentNumber || !ciName) {
logger.warning(fn + "Incident Number and Work Note were not passed. Could
not add work note");
return false;
}

logger.info(fn + "STARTING for Incident Number " + incidentNumber + "CI Name: "
+ ciName);

var ciHost;
var ciFQDN;
var addCIProcessResult;
var FOUND = false;

if ( ciName.indexOf("::" ) > 0 ) {
FOUND = true;
}
else {
ciFQDN = ciName;
}

if (FOUND === true)


{
var ciID = ciName.split("::")[0];
var cisource = ciName.split("::")[1];
if ( cisource.indexOf(".") > 0)
{
ciFQDN = cisource;
ciHosts = cisource.split(".")[0];
}
else { ciHost = cisource; }
}

var addCIIDProcess = process.create(config.ITSMTicketing.addTicketCIScript);

if (addCIIDProcess) {

/*
$1 = Incident Number
$2 = CI Information.
*/

addCIIDProcess.arg(incidentNumber);

addCIIDProcess.arg(ciID);

var processResultsCIID = process.runToExit(addCIIDProcess);


logger.debug(fn + "CIID Value: '" + ciID + "'");
var addCIIDProcessResults = addCIIDProcess.output();
logger.debug(fn + "CIID Value Result : '" + addCIIDProcessResults +
"'");

var addCIIDResultout = JSON.parse(addCIIDProcessResults);


var addCIIDResultOutput = addCIIDResultout.ExceptionMessage;

//if(addCIIDResultout === 'undefined')


// {
// addCIIDResultOutput = addCIIDResultout.ExceptionMessage;
// logger.debug(fn + "CIID Value Result found exception please
proceed next : '" + addCIIDResultOutput + "'");
//}

//addCIProcessResult = addCIIDProcessResults;
//logger.debug(fn + "Final CI's CIID Value: '" +
addCIProcessResult + "'");
if ( FOUND === false || addCIIDResultout.ExceptionMessage )
{

if ( addCIIDResultOutput.indexOf("is not found.") > 0 ||


addCIIDResultOutput.indexOf("Unable to read parameter") > 0 )

{
var addCIFQDNProcess =
process.create(config.ITSMTicketing.addTicketCIScript);

if (addCIFQDNProcess) {

/*
$1 = Incident Number
$2 = CI Information.
*/

addCIFQDNProcess.arg(incidentNumber);

addCIFQDNProcess.arg(ciFQDN);
var processFQDNResults = process.runToExit(addCIFQDNProcess);
logger.debug(fn + "CI Name: '" + ciFQDN + "'");
var addCIFQDNProcessResults = addCIFQDNProcess.output();
logger.debug(fn + "FQDN Value Result : '" + addCIFQDNProcessResults +
"'");
var addCIFQDNResultout = JSON.parse(addCIFQDNProcessResults);
var addCIFQDNResultOutput = addCIFQDNResultout.ExceptionMessage;
if (addCIFQDNResultout.ExceptionMessage)
{
if ( addCIFQDNResultOutput.indexOf("is not found.") > 0 ||
addCIFQDNResultOutput.indexOf("Unable to read parameter") > 0 )

{
var addCIHostProcess =
process.create(config.ITSMTicketing.addTicketCIScript);

if (addCIHostProcess) {

/*
$1 = Incident Number
$2 = CI Information.
*/

addCIHostProcess.arg(incidentNumber);

addCIHostProcess.arg(ciHost);

var processHostResults = process.runToExit(addCIHostProcess);


logger.debug(fn + "CI Name Host: '" + ciHost + "'");
var addCIHostProcessResults = addCIHostProcess.output();
var addCIHostResultout = JSON.parse(addCIHostProcessResults);
var adddCIHostResultOutput = addCIHostResultout.ExceptionMessage;

logger.debug(fn + "Host Value Result : '" + addCIHostProcessResults


+ "'");
}
}
}
}
}
}
}
}

/**
* Creates a ticket in ITSM
* Upon successful completion the ticket INC number is returned
* @function createTicket
* @param {string} situationID
* @param {string} description
* @param {string} urgency
* @param {string} impact
* @param {string} groupName
* @param {string} alertDescriptions
* @param {Object} customInfo
* @param {string} service
* @returns {boolean|string}
*/
function createTicket(situationID, description, urgency, impact, groupName,
alertDescriptions, customInfo, service, CI) {
var fn = "createTicket::";
logger.info(fn + "STARTING for Sit ID " + situationID + " Desc: " +
description);

// Validation with explicit log messages for passed data


if (!impact ) {
logger.warning(fn + "impact Parameter Not Found. Returning False");
return false;
}
if (!groupName) {
logger.warning(fn + "groupName Parameter Not Found. Returning False");
return false;
}
if (!service) {
logger.warning(fn + "Service Parameter Not Found. Returning False");
return false;
}
if (!alertDescriptions) {
logger.warning(fn + "alertDescriptions Parameter Not Found. Returning
False");
return false;
}
if (!customInfo) {
logger.warning(fn + "customInfo Parameter Not Found. Returning False");
return false;
}
if (!description) {
logger.warning(fn + "Description Parameter Not Found. Returning False");
return false;
}

if (!situationID) {
logger.warning(fn + "Situation ID Parameter Not Found. Returning False");
return false;
}
if (!urgency) {
logger.warning(fn + " Urgency Parameter Not Found. Returning False");
return false;
}

// Only proceed with processing if autoTicketCreate is true in config file


if (config.ITSMTicketing.autoTicketCreate === true) {

var productDetails = {};


productDetails.found = false;

var prodOfManufForTicket = "";

// Check the list of valid Urgency and Impact values. If not in list use
default.
if (config.ITSMTicketing.validUrgency.indexOf(urgency) === -1) {
urgency = config.ITSMTicketing.defaultUrgency;
}
if (config.ITSMTicketing.validImpact.indexOf(impact) === -1) {
impact = config.ITSMTicketing.defaultImpact;
}

logger.info(fn + "Script to call: '" +


config.ITSMTicketing.createTicketScript + "'");

var createTicketProcess =
process.create(config.ITSMTicketing.createTicketScript);

logger.info(fn + "Just Past process.create");

if (createTicketProcess) {
logger.info(fn + "Entered if createTicketProcess");

/*
$1- Username (NA\xsmoogitsm)
$2 – Situation description
$3 – Notes (All Alert Description with Hostname)
$4 – Urgency
$5 – Service name
$6 – Assignment Group
$7 – Situation ID
$8 - Impact
$9 - Product or Manufacturer
*/
logger.warning(fn + "Pre-Process ITSM productcontents:: " + service +
":::::" + JSON.stringify(customInfo));

// Get Product and Manufacturer from ITSM to create Ticket


if (service === "Upstream Technical Computing" || service ===
"Applications" || service === "Workplace Computing - Virtual Desktop") {

if (customInfo.ITSM) {
logger.warning(fn + "This is the current customInfo.ITSM
productcontents: '" + JSON.stringify(customInfo.ITSM) + "'");

if (customInfo.ITSM[groupName].ProductName &&
customInfo.ITSM[groupName].ProductName.length > 0 &&
customInfo.ITSM[groupName].ProductName !== "None") {
var ProductName = customInfo.ITSM[groupName].ProductName;
ProductName = ProductName.replace(/\ /g, "\%20");
logger.debug("This is the current customInfo.ITSM ProductName:" +
ProductName);
productDetails = getProductDetails(ProductName);

if(productDetails.found === true &&


productDetails.Manufacturer){
service = service;
}
}
else {
service = "";
}
}
}

alertDescriptions = moobotUtils.itsmSafe(alertDescriptions);
// alertDescriptions = alertDescriptions.replace(/\n/g, "\\
n").replace(/\r/g, " ").replace(/\t/g, " ");
// alertDescriptions = alertDescriptions.replace(/\\/g, "\\\\");
// alertDescriptions = alertDescriptions.replace(/"/g, '\\"');
// alertDescriptions = alertDescriptions.replace(/'/g, '\\"');
// alertDescriptions = alertDescriptions.replace(/«/g, "
").replace(/»/g, " ");
// alertDescriptions = alertDescriptions.replace(/\\n/g, "'\\n'");
description = description.replace(/\\/g, "\\\\");
description = description.replace(/"/g, '\\"');
description = description.replace(/'/g, '\\"');

if (groupName.match(/Database Administration-Oracle/g))
{

var descRE = /^(.*)\s+\[Ta.*$/gm;


desc = descRE.exec(description);

if(desc)
{
description = desc[1];
}

logger.debug(fn + "UserName: " + config.ITSMTicketing.userName);


createTicketProcess.arg(config.ITSMTicketing.userName);

logger.debug(fn + "Description: " + description);


createTicketProcess.arg(description);

logger.debug(fn + "alertDescriptions: " + alertDescriptions);


createTicketProcess.arg(alertDescriptions);

logger.debug(fn + "Urgency: " + urgency);


createTicketProcess.arg(urgency);

logger.debug(fn + "Service: " + service);


createTicketProcess.arg(service);

logger.debug(fn + "Group Name: " + groupName);


createTicketProcess.arg(groupName);

logger.debug(fn + "situationID: " + situationID);


createTicketProcess.arg(situationID);

logger.debug(fn + "impact: " + impact);


createTicketProcess.arg(impact);

createTicketProcess.arg(CI);

// This adds two optional parameters for product name and manufacturer
if we looked them up and found them
if(productDetails.found === true) {
if (productDetails.Product_Name &&
productDetails.Product_Name.length > 0) {
createTicketProcess.arg(productDetails.Product_Name);
logger.info(fn + "Product Name: " +
productDetails.Product_Name);
}

if (productDetails.Manufacturer &&
productDetails.Manufacturer.length > 0) {
createTicketProcess.arg(productDetails.Manufacturer);
logger.info(fn + "Manufacturer: " +
productDetails.Manufacturer);
}
}
var processResults = process.runToExit(createTicketProcess);

logger.debug(fn + "Process Results: '" + processResults + "'");

var createTicketProcessResults = createTicketProcess.output();

if (!createTicketProcessResults) {
logger.info(fn + "Bad results from createTicketProcessResults -
returning false");
return false;
}

logger.debug(fn + "RESULTS:createTicketProcessResults >>" +


createTicketProcessResults + "<<");

var incidentRE = /.*(INC\d+).*/g;

var ticketResult = incidentRE.exec(createTicketProcessResults);

if (!ticketResult) {
logger.warning(fn + "Incident number not found in results " +
createTicketProcessResults);

customInfo.ITSM[groupName].Results =
JSON.parse(createTicketProcessResults);
return "Ticket Error";
}

logger.debug(fn + "RESULTS:ticketResult >>" + ticketResult + "<<");

logger.info(fn + "Results from running the script: >>" +


createTicketProcessResults + "<< ");
return ticketResult[1];

else {
logger.warning(fn + "Process Object not created for " +
config.ITSMTicketing.createTicketScript + "<< ");
return false;
}
}
else {
logger.warning(fn + "Not Auto creating Ticket. SYSTEM SETTING
config.ITSMTicketing.autoTicketCreate set to false");
}

}
function itsmSafe(textToClean){
var result = textToClean.replace(/\n/g, "\\n").replace(/\r/g, " ").replace(/\
t/g, " ");
result = result.replace(/\\/g, "\\\\");
result = result.replace(/"/g, '\\"');
result = result.replace(/'/g, '\\"');
result = result.replace(/«/g, " ").replace(/»/g, " ");
result = result.replace(/\\n/g, "'\\n'");
return result;
}

// {"Product_ID":"PDC000000069553","Product_Name":"Atrium Orchestrator
Platform","Manufacturer":"BMC Software","Tier_1":"Software","Tier_2":"Software
Product","Tier_3":"Enterprise System Management","Status":"Enabled"}
function getProductDetails(ProductName){
var fn = "getProductDetails:: ";
var results = {};

ProductName = ProductName.replace(/\ /g, "\%20");

logger.debug(fn + "This is the current customInfo.ITSM ProductName:" +


ProductName);

var GetProductService = process.create(config.ITSMTicketing.getProductName);

GetProductService.arg(ProductName);

logger.info(fn + "Get the Product Name of Service " + ProductName);

var runResults = process.runToExit(GetProductService);

var processOutput = GetProductService.output();

if (processOutput && processOutput.length > 0) {


logger.warning(fn + "This is the Product Results: '" +
JSON.stringify(processOutput) + "'");

var prodvalue = {};

results = JSON.parse(processOutput);
results.found = true;
}
else {
results.found = false;
}
return results;
}

/**
* Update the Situation Support Group from the Status sent from ITSM
* Updates the Alerts for the Support Group fir the Situation as well
* @function updateStatusFromITSM
* @param {CEvent} situation
* @param {Object} customInfo
*/
function processChangesFromITSM(situation, customInfo) {
var fn = "updateStatusFromITSM:: ";
logger.info(fn + "STARTING");
if (!customInfo) {
return;
}

var result = false;


var sigChanged = false;
var sigId = situation.value("sig_id");
var changeType;

// Look through all of the incident numbers for this Situation


// Changes can come in two formats:
// Ticket Status Change
// Ticket Assignment Group Change
//
// Ticket Status will be writen to a top level key that matches the Ticket
Number
// INC00002435564:In Progress
//
// Assignment Group changes will be written to a top level key the matches the
// ticket number + 'AG'
// INC0000023242#AG:Infrastrucure Management Group
for (var iIdx = 0; iIdx < customInfo.ITSM.IncidentNumbers.length; iIdx++) {

var incidentNumber = customInfo.ITSM.IncidentNumbers[iIdx];


var agIncidentNumber = incidentNumber + "AG";
var supportGroup = "";

logger.info(fn + "Processing Incident number: " + incidentNumber);

// Process Ticket Status Changes


if (customInfo[incidentNumber]) {
logger.info(fn + "Value of custom_info." + incidentNumber + ":" +
customInfo[incidentNumber]);

var alertIds = [];

changeType = customInfo[incidentNumber];

// We have an incident number to process


// What is the value of teh incident number from ITSM
// We are expecting In Progress, Resolved and Closed.
// Once the incident number value has been processed this code will add
"-Processed" to prevent it from being
// processed until ITSM has made a change to it
switch (changeType) {

// We do not do anything with In Progress


case "In Progress":
logger.info(fn + "Status Change From ITSM. New Status: In
Progress");

customInfo[incidentNumber] = customInfo[incidentNumber] + "-


Processed";
sigChanged = true;
break;

// Update all the related alerts to resolved


case "Resolved":
logger.info(fn + "Status Change From ITSM. New Status:
Resolved");

alertIds = getAlertIdsForIncidentNumber(customInfo,
incidentNumber);
logger.info(fn + "Alert IDs for Inc: " + alertIds);

moobotUtils.updateAlertState(alertIds, 9);

supportGroup = getSupportGroupFromIncNum(customInfo,
incidentNumber);

if (supportGroup) {
customInfo.ITSM[supportGroup].ITSMLastStatus = "Resolved";
if (!customInfo.ITSM.AlertsResolved) {
customInfo.ITSM.AlertsResolved = [];
}
customInfo.ITSM.AlertsResolved =
botUtils.uniqArray(moobotUtils.pushArray(customInfo.ITSM.AlertsResolved,
alertIds));
}
result = true;
sigChanged = true;
customInfo[incidentNumber] = customInfo[incidentNumber] + "-
Processed";
var ITSM = {};
ITSM = customInfo.ITSM;
var newAssignmentGroup = supportGroup + "-Resolved";
logger.debug(fn + "GroupsWithTickets before change: " +
ITSM.groupsWithTickets);
ITSM.groupsWithTickets =
ITSM.groupsWithTickets.filter(function(i){return i != supportGroup;});
ITSM.groupsWithTickets.push(newAssignmentGroup);
logger.debug(fn + "GroupsWithTickets after change: " +
ITSM.groupsWithTickets)
logger.debug(fn + "ITSM Before change: " +
JSON.stringify(ITSM));
ITSM[newAssignmentGroup] = ITSM[supportGroup];
logger.debug(fn + "ITSM After Add New Group: " +
JSON.stringify(ITSM));
// var AG = "\"" + supportGroup + "\"";
delete ITSM[supportGroup];
logger.debug(fn + "ITSM After Remove Old Group: " +
ITSM[supportGroup]);
logger.debug(fn + "ITSM After Remove Old Group: " +
JSON.stringify(ITSM));
// * * Step 5 - Update Situation Record
logger.debug(fn + "ITSM Object:" + ITSM);
customInfo.ITSM = ITSM;
situation.setCustomInfo(customInfo);
moogdb.updateSituation(situation);

if (moobotUtils.checkAllSigAlertState(sigId, 9) === true) {


logger.info(fn + "Sit: '" + sigId + "' All Alerts Resolved.
Resolving Situation");

// Resolve the Situation


moogdb.resolveSituation(sigId);
}
else {
logger.info(fn + "Sit: '" + sigId + "' NOT All Alerts
Resolved. Can't Resolve Situation");
}

break;
case "Cancelled":
logger.info(fn + "Status Change From ITSM. New Status:
Resolved");

alertIds = getAlertIdsForIncidentNumber(customInfo,
incidentNumber);
logger.info(fn + "Alert IDs for Inc: " + alertIds);

moobotUtils.updateAlertState(alertIds, 9);

supportGroup = getSupportGroupFromIncNum(customInfo,
incidentNumber);

if (supportGroup) {
customInfo.ITSM[supportGroup].ITSMLastStatus = "Resolved";
if (!customInfo.ITSM.AlertsResolved) {
customInfo.ITSM.AlertsResolved = [];
}
customInfo.ITSM.AlertsResolved =
botUtils.uniqArray(moobotUtils.pushArray(customInfo.ITSM.AlertsResolved,
alertIds));
}
result = true;
sigChanged = true;
customInfo[incidentNumber] = customInfo[incidentNumber] + "-
Processed";
var ITSM = {};
ITSM = customInfo.ITSM;
var newAssignmentGroup = supportGroup + "-Cancelled";
logger.debug(fn + "GroupsWithTickets before change: " +
ITSM.groupsWithTickets);
ITSM.groupsWithTickets =
ITSM.groupsWithTickets.filter(function(i){return i != supportGroup;});
ITSM.groupsWithTickets.push(newAssignmentGroup);
logger.debug(fn + "GroupsWithTickets after change: " +
ITSM.groupsWithTickets)
logger.debug(fn + "ITSM Before change: " +
JSON.stringify(ITSM));
ITSM[newAssignmentGroup] = ITSM[supportGroup];
logger.debug(fn + "ITSM After Add New Group: " +
JSON.stringify(ITSM));
delete ITSM[supportGroup];
logger.debug(fn + "ITSM After Remove Old Group: " +
JSON.stringify(ITSM));
// * * Step 5 - Update Situation Record
logger.debug(fn + "ITSM Object:" + ITSM);
customInfo.ITSM = ITSM;
situation.setCustomInfo(customInfo);
moogdb.updateSituation(situation);

if (moobotUtils.checkAllSigAlertState(sigId, 9) === true) {


logger.info(fn + "Sit: '" + sigId + "' All Alerts Resolved.
Resolving Situation");
// Resolve the Situation
moogdb.resolveSituation(sigId);
}
else {
logger.info(fn + "Sit: '" + sigId + "' NOT All Alerts
Resolved. Can't Resolve Situation");
}
break;
// Update all the related alerts to closed
case "Closed":
logger.info(fn + "Status Change From ITSM. New Status:
Closed");

alertIds = getAlertIdsForIncidentNumber(customInfo,
incidentNumber);

moobotUtils.updateAlertState(alertIds, 9);

supportGroup = getSupportGroupFromIncNum(customInfo,
incidentNumber);
var ITSM = {};
ITSM = customInfo.ITSM;
var newAssignmentGroup = supportGroup + "-Cancelled";
logger.debug(fn + "GroupsWithTickets before change: " +
ITSM.groupsWithTickets);
ITSM.groupsWithTickets =
ITSM.groupsWithTickets.filter(function(i){return i != supportGroup;});
ITSM.groupsWithTickets.push(newAssignmentGroup);
logger.debug(fn + "GroupsWithTickets after change: " +
ITSM.groupsWithTickets)
logger.debug(fn + "ITSM Before change: " +
JSON.stringify(ITSM));
ITSM[newAssignmentGroup] = ITSM[supportGroup];
logger.debug(fn + "ITSM After Add New Group: " +
JSON.stringify(ITSM));
// var AG = "\"" + supportGroup + "\"";
delete ITSM[supportGroup];
logger.debug(fn + "ITSM After Remove Old Group: " +
ITSM[supportGroup]);
logger.debug(fn + "ITSM After Remove Old Group: " +
JSON.stringify(ITSM));
// * * Step 5 - Update Situation Record
logger.debug(fn + "ITSM Object:" + ITSM);
customInfo.ITSM = ITSM;
situation.setCustomInfo(customInfo);
moogdb.updateSituation(situation);
if (supportGroup) {
customInfo.ITSM[supportGroup].ITSMLastStatus = "Closed";
if (!customInfo.ITSM.AlertsClosed) {
customInfo.ITSM.AlertsClosed = [];
}
customInfo.ITSM.AlertsClosed =
botUtils.uniqArray(moobotUtils.pushArray(customInfo.ITSM.AlertsClosed, alertIds));
}
result = true;
sigChanged = true;
customInfo[incidentNumber] = customInfo[incidentNumber] + "-
Processed";
if (moobotUtils.checkAllSigAlertState(sigId, 9) === true) {
logger.info(fn + "Sit: '" + sigId + "' All Alerts Closed.
Closing Situation");
// Close the Situation
moogdb.closeSituation(sigId, moogdb.CLOSE_UNUSED_ALERTS);
}
else {
logger.info(fn + "Sit: '" + sigId + "' NOT All Alerts
Closed. Can't Close Situation");
}
break;

// do nothing because the status change has already been processed


case "In Progress-Processed", "Resolved-Processed", "Closed-
Processed":

break;
default:
logger.warning(fn + "Unknown ITSM Ticket Status. Not handling
change.");
}
}

// Process Assignment Group Changes


if (customInfo[agIncidentNumber]) {
logger.info(fn + "Value of custom_info." + agIncidentNumber + ":" +
customInfo[agIncidentNumber]);
var newAssignmentGroup = customInfo[agIncidentNumber];

delete(customInfo[agIncidentNumber]);
sigChanged = true;

if(customInfo.ITSM.groupsWithTickets.indexOf(newAssignmentGroup) >= 0){


// There is all ready an assignment group with that name
logger.warning(fn + "Not processing request to change Assignment
Group. The requested group already has a ticket in this situation");
}
else {
// There are no other group with this name
supportGroup = getSupportGroupFromIncNum(customInfo,
incidentNumber);
logger.debug(fn + "Changing support Group From: " + supportGroup);

var ITSM = {};


ITSM = customInfo.ITSM;

// * * Step 1 - Remove Support Group from array of ITSM Groups


logger.debug(fn + "GroupsWithTickets before change: " +
ITSM.groupsWithTickets);
ITSM.groupsWithTickets = ITSM.groupsWithTickets.filter(function(i)
{return i != supportGroup;});
ITSM.groupsWithTickets.push(newAssignmentGroup);
logger.debug(fn + "GroupsWithTickets after change: " +
ITSM.groupsWithTickets);

// * * Step 2 - Copy branch from original Support group to new


support group
logger.debug(fn + "ITSM Before change: " + JSON.stringify(ITSM));
ITSM[newAssignmentGroup] = ITSM[supportGroup];
logger.debug(fn + "ITSM After Add New Group: " +
JSON.stringify(ITSM));

// * * Step 3 - Delete Original Support Group Branch


delete(ITSM[supportGroup]);
logger.debug(fn + "ITSM After Remove Old Group: " +
JSON.stringify(ITSM));

// * * Step 4 - Update all alerts with new support group

moobotUtils.updateAlertSupportGroup(ITSM[newAssignmentGroup].AlertsHavingTickets,
newAssignmentGroup);

// * * Step 5 - Update Situation Record


logger.debug(fn + "ITSM Object:" + ITSM);

customInfo.ITSM = ITSM;

sigChanged = true;
}
}
}

// If the situation has been changed


if (sigChanged === true) {
situation.setCustomInfo(customInfo);
moogdb.updateSituation(situation);
var sigTotalAlerts = 0;

// Close the situation if all the alerts are closed


if (customInfo.ITSM.AlertsClosed && customInfo.ITSM.AlertsClosed.length >
0) {
logger.info(fn + "Total Closed Alerts: " +
customInfo.ITSM.AlertsClosed.length);

sigTotalAlerts = situation.value("total_alerts");

logger.info(fn + "Total Alerts for Situation: " + sigTotalAlerts);

if (sigTotalAlerts === customInfo.ITSM.AlertsClosed.length) {

// Close the Situation


moogdb.closeSituation(sigId, moogdb.CLOSE_UNUSED_ALERTS);
}
}

// Otherwise Resolve the Situation if all the alerts have been resolved
// TODO this is only working if all the alerts are for the same support
group and there is only the one support group.
else if (customInfo.ITSM.AlertsResolved &&
customInfo.ITSM.AlertsResolved.length > 0) {
logger.info(fn + "Total Resolved Alerts: " +
customInfo.ITSM.AlertsResolved.length);

sigTotalAlerts = situation.value("total_alerts");

logger.info(fn + "Total Alerts for Situation: " + sigTotalAlerts);


if (sigTotalAlerts === customInfo.ITSM.AlertsResolved.length) {

// Resolve the Situation


moogdb.resolveSituation(sigId);
}
}
}
}

/**
* @function getSupportGroupFromIncNum
* @param {Object} customInfo
* @param {string} incidentNumber
* @returns {string| boolean}supportGroup
*/
function getSupportGroupFromIncNum(customInfo, incidentNumber) {
var fn = "getSupportGroupFromIncNum ";

logger.info(fn + "STARTING");

var supportGroup = "";

if (!customInfo || !incidentNumber) {
return false;
}
if (customInfo.ITSM && customInfo.ITSM.groupsWithTickets &&
customInfo.ITSM.groupsWithTickets.length > 0) {
logger.info(fn + "Groups with tickets: " +
customInfo.ITSM.groupsWithTickets);
for (var gIdx = 0; gIdx < customInfo.ITSM.groupsWithTickets.length; gIdx++)
{
var currentGroup = customInfo.ITSM.groupsWithTickets[gIdx];
logger.info(fn + "currentGroup: " + currentGroup);
if (customInfo.ITSM[currentGroup] &&
customInfo.ITSM[currentGroup].IncidentNumber &&
customInfo.ITSM[currentGroup].IncidentNumber === incidentNumber) {
supportGroup = currentGroup;
logger.info(fn + "Support Group for Incident Number: " +
incidentNumber + " is: " + supportGroup);
}
}
}
else {
logger.info(fn + "There are no Support groups for Situation");
}

return supportGroup;
}

/**
* @function getAlertIdsForIncidentNumber
* @param {Object} customInfo
* @param {string} incidentNumber
* @returns {Array} Alert IDs
*/
function getAlertIdsForIncidentNumber(customInfo, incidentNumber) {
var fn = "getAlertIdsForIncidentNumber:: ";
logger.debug(fn + "STARTING");

var alertIds = [];

if (!customInfo || !incidentNumber) {
return alertIds;
}

var supportGroup = getSupportGroupFromIncNum(customInfo, incidentNumber);

logger.info(fn + "Support group for incident number is: " + supportGroup);

if (customInfo.ITSM && customInfo.ITSM[supportGroup] &&


customInfo.ITSM[supportGroup].AlertsHavingTickets &&
customInfo.ITSM[supportGroup].AlertsHavingTickets.length > 0) {
alertIds = customInfo.ITSM[supportGroup].AlertsHavingTickets;
}

logger.info(fn + "Alert IDs for Support Group '" + supportGroup + "' IDs: " +
alertIds);

return alertIds;

/**
* Called when a situation is Created or Updated
* Reads the Support Groups that have or need tickets from
customInfo.ITSM.groupsWithTickets
* @function situationProcess
* @param {CEvent} inBoundSituation
*/
function situationProcess(inBoundSituation) {
var fn = "situationProcess:: ";
var sigId = inBoundSituation.value('sig_id');

var situation = moogdb.getSituation(sigId);

var sitDescription = situation.value("description");

var situationChange = false;

logger.info(fn + "STARTING: Sit Id: '" + sigId + "' Description: '" +


sitDescription + "'");

var customInfo = situation.value('custom_info');

if (!customInfo) {
logger.warning(fn + "Situation Does not have custom_info. Waiting for
SituationMgr to add. Exiting ITSM Integration Moobot. EITSM001");
return;
}

logger.info(fn + "config.ITSMTicketing.autoTicketCreate = " +


config.ITSMTicketing.autoTicketCreate);

// Only create the ticket if the config.ITSMTicketing.autoTicketCreate setting


is true in the config file
if (config.ITSMTicketing.autoTicketCreate === true) {
if (customInfo.ITSM) {
logger.debug(fn + "This is the current customInfo.ITSM contents: '" +
JSON.stringify(customInfo.ITSM) + "'");

if (customInfo.ITSM.groupsWithTickets) {

if (customInfo.ITSM.groupsWithTickets.length > 0) {
logger.debug(fn + "Number of groups with tickets: '" +
customInfo.ITSM.groupsWithTickets.length + "'");

var sitAllAlertIds = moogdb.getSituationAlertIds(sigId, false);

for (var gIdx = 0; gIdx <


customInfo.ITSM.groupsWithTickets.length; gIdx++) {

// Get the Group Name for the Current Group


var groupName = customInfo.ITSM.groupsWithTickets[gIdx];

var alertIds = [];


var alertHosts = [];
var incidentNotes = "";
var incidentAlerts = {};

logger.debug(fn + "Array Position: " + gIdx + " Group


Name: '" + groupName + "'");

// For each group perform a couple of checks to see if we


need to do anything with Tickets

// Perform actions based on Ticket Status


if (customInfo.ITSM[groupName] &&
customInfo.ITSM[groupName].TicketStatus) {
logger.info(fn + "GRP: '" + groupName + "' -
TicketStatus: '" + customInfo.ITSM[groupName].TicketStatus + "'");

// **** Create Tickets ****

// Create new Incident if TicketStatus is Required OR


// TicketStatus is Update and there is no Incident
Number
if (customInfo.ITSM[groupName].TicketStatus ===
"Required" ||
(customInfo.ITSM[groupName].TicketStatus ===
"Update" &&
(customInfo.ITSM[groupName].IncidentNumber.length
=== 0 || customInfo.ITSM[groupName].IncidentNumber == false) ) )
{

logger.debug(fn + "GRP: '" + groupName + "'


Processing Create Incident");
logger.debug(fn + "GRP: '" + groupName + "'
AlertsNeedingTickets: '" + customInfo.ITSM[groupName].AlertsNeedingTickets.length +
"'");
logger.debug(fn + "GRP: '" + groupName + "'
AlertsHavingTickets: '" + customInfo.ITSM[groupName].AlertsHavingTickets.length +
"'");
logger.debug(fn + "GRP: '" + groupName + "'
IncidentNumber: '" + customInfo.ITSM[groupName].IncidentNumber + "'");
logger.debug(fn + "GRP: '" + groupName + "'
Alert Ids: '" + alertIds + "'");

// * * Step 1 - Create list of Alert IDs for the


description and work notes

// Get list of Alerts that need tickets for this


group
alertIds =
customInfo.ITSM[groupName].AlertsNeedingTickets;
logger.debug(fn + "GRP: '" + groupName + "'
Alert Ids: '" + alertIds + "'");

// * * Step 2 - Build object of Alerts so we don't


have to read them over and over
incidentAlerts = getAlerts(alertIds,
config.ITSMTicketing.maxAlertsForIncident);

// * * Step 3 - Build the detailed description


from the Alerts

// Build out the description based on Groups Alerts


logger.debug(fn + "CALLING incidentNotes(" +
alertIds + ")");
incidentNotes =
getAlertDescriptions(incidentAlerts);

if
(config.ITSMTicketing.includeAllAlertsInInitialTicketNotes === true) {
logger.debug(fn + "CALLING
getRemainingincidentNotes(" + sitAllAlertIds.alert_ids + ", " + alertIds + ", " +
incidentNotes + ")");
if(sitAllAlertIds.alert_ids.length >
alertIds.length){
// Get the Alert IDs that are in the
Situation but not for this group
var remainingAlertIds =
botUtils.arrayDifference(sitAllAlertIds.alert_ids, alertIds);
logger.debug(fn + "Remaining Alert IDs to
Process: " + remainingAlertIds);

// Get an Object of the remaining Alerts


var remainingAlerts =
getAlerts(remainingAlertIds, config.ITSMTicketing.maxAlertsForIncident -
alertIds.length);

incidentNotes +=
config.ITSMTicketing.ticketLineBreak + config.ITSMTicketing.ticketLineFeed;
incidentNotes +=
getAlertDescriptions(remainingAlerts)+ config.ITSMTicketing.ticketLineFeed;
}
}

incidentNotes +=
config.ITSMTicketing.ticketLineBreak + config.ITSMTicketing.ticketLineFeed + "The
Moogsoft situation id = " + sigId + config.ITSMTicketing.ticketLineFeed;

// THE LOGIC FOR FIGURING OUT THE SERVICE NEEDS TO


GO HERE.
var ticketService =
(customInfo.ITSM[groupName].Service) ? customInfo.ITSM[groupName].Service :
"Service Name";
var TickCI = (customInfo.ITSM[groupName].CI) ?
customInfo.ITSM[groupName].CI : "CI Name";
// Create the ticket for the group and update this
group with the ticket number
var incidentNumber = createTicket(sigId,
sitDescription, customInfo.ITSM[groupName].Urgency,
customInfo.ITSM[groupName].Impact, groupName, incidentNotes, customInfo,
ticketService, TickCI);

logger.info(fn + "GRP: '" + groupName + "' Ticket


Number: '" + incidentNumber + "'");

if(incidentNumber === false){


logger.warning(fn + "This incident number
returned false. Stop processing this group. ");
// this is an indication that there was a
falure creating the ticket.
// This sets TicketStatus to Created of the in
memory object
// customInfo.ITSM[groupName].TicketStatus =
"Failed";
}
// We have an Incident Number and can continue
processing
else {

// Update the group and Situation with the


Incident number

customInfo.ITSM[groupName].IncidentNumber =
incidentNumber;

if (!customInfo.ITSM.IncidentNumbers) {
customInfo.ITSM.IncidentNumbers = [];
}

customInfo.ITSM.IncidentNumbers.push(incidentNumber);

// Update Group Alert Tracking Keys


customInfo.ITSM[groupName].AlertsNeedingTickets
= [];

// Since this is a create we can set the


AlertHaving Tickets to the AlertID List
customInfo.ITSM[groupName].AlertsHavingTickets
= alertIds;

// * * Step 4 - Add ticket number to Alerts

addTicketNumberToAlerts(alertIds,
incidentNumber, situation.value("sig_id"));

// * * Step 5 - Add CI relationship data to


Ticket

alertHosts =
customInfo.ITSM[groupName].HostsToAdd;

if (alertHosts && alertHosts.length > 0) {


for (var hIdx = 0; hIdx <
alertHosts.length; hIdx++) {
addCI(incidentNumber,
alertHosts[hIdx]);
}
if
(customInfo.ITSM[groupName].HostsAdded.length > 0) {

customInfo.ITSM[groupName].HostsAdded.concat(customInfo.ITSM[groupName].HostsToAdd)
;
}
else {
customInfo.ITSM[groupName].HostsAdded =
customInfo.ITSM[groupName].HostsToAdd;
}
customInfo.ITSM[groupName].HostsToAdd = [];
}

// * * Step 6 - Add each alert to Incident


Work Notes

alerts2WorkNotes(incidentNumber,incidentAlerts);

// * * Step 7 - Update group with success

// This sets TicketStatus to Created of the in


memory object
customInfo.ITSM[groupName].TicketStatus =
"Created";

}
situationChange = true;
}

// **** Update Incidents ****


// Since this is an update all we need to do is process
the new alerts
// 1 - Add Incident Work Notes
// 2 - Update Alerts with Incident Number
// 3 - Add any new CIs to the Incident

else if (customInfo.ITSM[groupName].TicketStatus ===


"Update") {
// Update indicated that this group needs a ticket
to be updated
logger.debug(fn + "GRP: '" + groupName + "'
Processing Update Incident");
logger.debug(fn + "GRP: '" + groupName + "'
AlertsNeedingTickets: '" + customInfo.ITSM[groupName].AlertsNeedingTickets.length +
"'");
logger.debug(fn + "GRP: '" + groupName + "'
AlertsNeedingTickets: '" + customInfo.ITSM[groupName].AlertsNeedingTickets + "'");

logger.debug(fn + "GRP: '" + groupName + "'


AlertsHavingTickets: '" + customInfo.ITSM[groupName].AlertsHavingTickets.length +
"'");
logger.debug(fn + "GRP: '" + groupName + "'
AlertsHavingTickets: '" + customInfo.ITSM[groupName].AlertsHavingTickets + "'");

logger.debug(fn + "GRP: '" + groupName + "'


IncidentNumber: '" + customInfo.ITSM[groupName].IncidentNumber + "'");
logger.debug(fn + "GRP: '" + groupName + "'
TicketStatus: '" + customInfo.ITSM[groupName].TicketStatus + "'");

// Check and see if there are any alerts that need


tickets
if
(customInfo.ITSM[groupName].AlertsNeedingTickets.length > 0) {
logger.info(fn + "This support group have new
alerts to add to the ticket: '" + customInfo.ITSM[groupName].AlertsNeedingTickets +
"'");
// we have alerts to add to ticket

// * * Step 1 - Get the new Alert IDs


alertIds =
customInfo.ITSM[groupName].AlertsNeedingTickets;
logger.debug(fn + "GRP: '" + groupName + "'
Alert Ids: '" + alertIds + "'");

// * * Step 2 - Create Object of Alerts to


process
incidentAlerts = getAlerts(alertIds,
config.ITSMTicketing.maxAlertsForIncident);

// * * Step 3 - Add Ticket Number to Alerts


addTicketNumberToAlerts(alertIds,
customInfo.ITSM[groupName].IncidentNumber, situation.value("sig_id"));

// * * Step 4 - Add each alert to Incident


Work Notes

alerts2WorkNotes(customInfo.ITSM[groupName].IncidentNumber,incidentAlerts);

// * * Step 5 - All any new CIs to ticket


alertHosts =
customInfo.ITSM[groupName].HostsToAdd;

if (alertHosts && alertHosts.length > 0) {


for (var hIdx = 0; hIdx <
alertHosts.length; hIdx++) {

addCI(customInfo.ITSM[groupName].IncidentNumber, alertHosts[hIdx]);
}
if
(customInfo.ITSM[groupName].HostsAdded.length > 0) {

customInfo.ITSM[groupName].HostsAdded.concat(customInfo.ITSM[groupName].HostsToAdd)
;
}
else {
customInfo.ITSM[groupName].HostsAdded =
customInfo.ITSM[groupName].HostsToAdd;
}
customInfo.ITSM[groupName].HostsToAdd = [];
}
// * * Step 6 - Update group with success and
save
customInfo.ITSM[groupName].TicketStatus =
"Updated";

customInfo.ITSM[groupName].AlertsHavingTickets
= customInfo.ITSM[groupName].AlertsHavingTickets.concat(alertIds);
customInfo.ITSM[groupName].AlertsHavingTickets
= botUtils.uniqArray(customInfo.ITSM[groupName].AlertsHavingTickets);
customInfo.ITSM[groupName].AlertsNeedingTickets
= [];

situationChange = true;
}
}
}
else {
logger.info(fn + "TicketStatus property not found for
group '" + groupName + "'");
}
}
if(situationChange === true){
situation.setCustomInfo(customInfo);
moogdb.setSigCustomInfo(situation);
}
}
else {
logger.info(fn + "The group count for
custom_info.ITSM.groupsWithTickets was zero");
}
}
else {
logger.info(fn + "There was not a
custom_info.ITSM.groupsWithTickets property. Exiting moobot");
}
}
else {
logger.info(fn + "custom_info did not contain ITSM. Exiting Moobot");
return;
}
}
else {
// Don't create the ITSM ticket
logger.warning(fn + "Checking if tickets are required. SYSTEM SETTING
config.ITSMTicketing.autoTicketCreate set to false");
}

// * * Process All Tickets for updates from ITSM.

// Check the situation to see if there have been any changes from ITSM and
update the situation and alerts
if (customInfo.ITSM && customInfo.ITSM.IncidentNumbers &&
customInfo.ITSM.IncidentNumbers.length > 0) {
logger.info(fn + "Sending custom_info over to updateStatusFromITSM");
processChangesFromITSM(situation, customInfo);
}

situation = moogdb.getSituation(sigId);
situation.forward(config.ITSMTicketing.nextMoolet);
logger.info(fn + "ENDING Sending situation to next moolet: " +
config.ITSMTicketing.nextMoolet);
inBoundSituation.forward(this);
}

/**
* @function alerts2WorkNotes
* @param {string} incidentNumber
* @param {Object} incidentAlerts
* @returns {boolean|Object} false if set to not add note or add note failed,
otherwise object containing the results
*/
function alerts2WorkNotes(incidentNumber, incidentAlerts) {
var fn = "addWoralerts2WorkNoteskNote:: ";
var results = {};
if (!incidentAlerts) {
logger.warning(fn + "Missing parameter incidentAlerts");
return results;
}
if (!incidentAlerts.alertIds) {
logger.warning(fn + "incidentAlerts is missing alertIds");
return results;
}
if (incidentAlerts.alertIds.length < 1) {
logger.warning(fn + "incidentAlerts.alertIds length is: " +
incidentAlerts.alertIds.length);
return results;
}
logger.debug(fn + "Processing Alert IDs: " + incidentAlerts.alertIds);

for (var cIdx = 0; cIdx < incidentAlerts.alertIds.length; cIdx++) {


var alert_id = incidentAlerts.alertIds[cIdx];
logger.debug(fn + "Current Alert ID: " + alert_id);
var alert = incidentAlerts[alert_id];
if(alert) {
var alertDescForWorkNotes = "";

var status = "Open";


var description = alert.value("description");
var host = alert.value("source");
var external_id = alert.value("external_id");
var class = alert.value("class");
var tier = "NA";
var impact = "NA";
var urgency = "NA";

var alertCustomInfo = alert.getCustomInfo();


if(alertCustomInfo){
tier = botUtils.isObjectDefined(alertCustomInfo,"CMDB.System.Tier")
? botUtils.getObjectValue(alertCustomInfo, "CMDB.System.Tier") : "NA";
impact = botUtils.isObjectDefined(alertCustomInfo,"ITSM.Impact") ?
botUtils.getObjectValue(alertCustomInfo, "ITSM.Impact") : "NA";
urgency =
botUtils.isObjectDefined(alertCustomInfo,"ITSM.Urgency") ?
botUtils.getObjectValue(alertCustomInfo, "ITSM.Urgency") : "NA";
}

logger.debug(fn + "alert_id: " + alert_id);


logger.debug(fn + "status: " + status);
logger.debug(fn + "description: " + description);
logger.debug(fn + "host: " + host);
logger.debug(fn + "external_id: " + external_id);
logger.debug(fn + "tier: " + tier);
logger.debug(fn + "impact: " + impact);
logger.debug(fn + "urgency: " + urgency);

// AlertID <Alert ID> : <Status> : <Description>


// External ID: <External ID>
// Tier: <Tier>
// Impact: <impact>
// Urgency:<Urgency>

alertDescForWorkNotes += "AlertID: " + alert_id + " : " + status + " :


" + description + config.ITSMTicketing.ticketLineFeed;
///Adding host details after request came after go live//
alertDescForWorkNotes += "Class:" + class +
config.ITSMTicketing.ticketLineFeed;
alertDescForWorkNotes += "Host: " + host +
config.ITSMTicketing.ticketLineFeed;
///Ending/////////
alertDescForWorkNotes += "External ID: " + external_id +
config.ITSMTicketing.ticketLineFeed;
alertDescForWorkNotes += "Tier: " + tier +
config.ITSMTicketing.ticketLineFeed;
alertDescForWorkNotes += "Impact: " + impact +
config.ITSMTicketing.ticketLineFeed;
alertDescForWorkNotes += "Urgency: " + urgency;

logger.debug(fn + "Id: '" + alert_id + "' Description: '" +


alertDescForWorkNotes + "'");

results = addWorkNote(incidentNumber, alertDescForWorkNotes);


}
else {
logger.warning(fn + "Not able to read alert for ID: " + alert_id);
}
}
}

/*
<Alert Description>
Host: <Host>
AlertID:<moog alert ID
-----------------------------------
<Alert Description>
Host: <Host>
AlertID:<moog alert ID
-----------------------------------
<Alert Description>
Host: <Host>
AlertID:<moog alert ID
-----------------------------------
The Moogsoft situation id = <Situation ID>
*/

/**
* * {
* alertIds [12345,12346],
* 12345 : {CEvent},
* 12346 : {CEvent}
* }
* @function getAlertDescriptions
* @param {Object} incidentAlerts
* @returns {string|boolean}
*/
function getAlertDescriptions(incidentAlerts) {
var fn = "getAlertDescriptions:: ";
var results = "";

if (!incidentAlerts) {
logger.warning(fn + "Missing parameter incidentAlerts");
return results;
}
if (!incidentAlerts.alertIds) {
logger.warning(fn + "incidentAlerts is missing alertIds");
return results;
}
if (incidentAlerts.alertIds.length < 1) {
logger.warning(fn + "incidentAlerts.alertIds length is: " +
incidentAlerts.alertIds.length);
return results;
}
logger.debug(fn + "Processing Alert IDs: " + incidentAlerts.alertIds);

var incidentAlertDescription = "";

for (var cIdx = 0; cIdx < incidentAlerts.alertIds.length; cIdx++) {


var alert_id = incidentAlerts.alertIds[cIdx];
logger.debug(fn + "Current Alert ID: " + alert_id);
var alert = incidentAlerts[alert_id];
if(alert) {
var alertDescForIncident = "";

var description = alert.value("description");


var host = alert.value("source");
var class = alert.value("class");

if (cIdx > 0) {
alertDescForIncident += config.ITSMTicketing.ticketLineBreak +
config.ITSMTicketing.ticketLineFeed;
}
alertDescForIncident += "Please see Work Detail for all Alerts
associated with this Incident ID" + config.ITSMTicketing.ticketLineFeed;
alertDescForIncident +=
"-----------------------------------------------------------------" +
config.ITSMTicketing.ticketLineFeed;
alertDescForIncident +=
botUtils.maxChars(description,config.ITSMTicketing.maxAlertDescriptionSize) +
config.ITSMTicketing.ticketLineFeed;
alertDescForIncident += "Class: " + class +
config.ITSMTicketing.ticketLineFeed;
alertDescForIncident += "Host: " + host +
config.ITSMTicketing.ticketLineFeed;
alertDescForIncident += "AlertID: " + alert_id +
config.ITSMTicketing.ticketLineFeed;
// var alertDescForIncident = "Alert " + alert.value("alert_id") + " :
Open : " + moobotUtils.maxChars(alert.value("source") + " : " +
alert.value("description"), config.ITSMTicketing.maxalertDescForIncidentSize);

logger.debug(fn + "Id: '" + alert_id + "' Description: '" +


alertDescForIncident + "'");

incidentAlertDescription += alertDescForIncident;

logger.debug(fn + "incidentalertDescForIncident: '" +


incidentAlertDescription + "'");
}
else {
logger.warning(fn + "Not able to read alert for ID: " + alert_id);
}
}
results = botUtils.maxChars(incidentAlertDescription,
config.ITSMTicketing.maxTotalAlertDescriptionSize);
logger.debug(fn + "Final Alert Description: " + results + "'");
return results;
}

/**
* from an array of alert IDs returns an object of Alerts by key=alert_id
* {
* alertIds [12345,12346],
* 12345 : {CEvent},
* 12346 : {CEvent}
* }
* @function getAlerts
* @param {Array} alert_ids
* @param {number} limit
* @returns {Object}
*/
function getAlerts(alert_ids,limit) {
var fn= "getAlerts:: ";

var alerts={};
alerts.alertIds = [];

logger.debug(fn + "Alert IDs to process: " + alert_ids);

if(!alert_ids){
logger.debug(fn + "AlertIDs paramiter is required.");
return alerts;
}

var defaultMax = 20;

// Applay a limiter if needed.


if(!limit){
logger.debug(fn + "limit parameter not passed. Using hard default: " +
defaultMax);
limit = defaultMax;
}
else {
logger.debug(fn + "Limit parameter passed: " + limit);
}
if (alert_ids && botUtils.isArray(alert_ids) && alert_ids.length > 0) {

var numAlerts = alert_ids.length;

if (limit > numAlerts) {


limit = numAlerts;
}

logger.debug(fn + "Processing Alert IDs: " + alert_ids);

// Get the alerts for this the alert IDs

for (var alIdx = 0; alIdx < limit; alIdx++) {


alerts.alertIds.push(alert_ids[alIdx]);

var alert = moogdb.getAlert(alert_ids[alIdx]);

if(alert) {
var alert_id = alert.value("alert_id");
alerts[alert_id] = alert;

logger.debug(fn + "Processing Alert ID: " + alert.value("alert_id")


+ " Desc: " + alert.value("description"));
}
}
}

logger.debug(fn + "processed '" + alerts.alertIds.length + " Alerts. IDs " +


alerts.alertIds);

return alerts;
}

/**
* @function addTicketNumberToAlerts
* @param {Array} alertIds
* @param {string} incidentNumber
* @param {string} sitID
*/
function addTicketNumberToAlerts(alertIds, incidentNumber, sitID) {
var fn = "addTicketNumberToAlerts:: ";
if (!alertIds) {
logger.debug(fn + "alertIds Not Valid");
return false;
}
if (!incidentNumber) {
logger.debug(fn + "incidentNumber Not Valid");
return false;
}
if (alertIds && alertIds.length > 0 && incidentNumber) {
logger.info(fn + "Adding incident Number: '" + incidentNumber + "' to
Alerts '" + alertIds + "' Total Alerts: '" + alertIds.length + "'");
var custom_info = {};
custom_info.ITSM = {};
custom_info.ITSM.TicketNumber = incidentNumber;
custom_info.ITSM.SituationID = sitID;
for (var aIdx = 0; aIdx < alertIds.length; aIdx++) {
logger.debug(fn + "AlertID: '" + alertIds[aIdx] + "' - TicketNumber: '"
+ incidentNumber + "'");
moogdb.setAlertCustomInfo(alertIds[aIdx], custom_info, true);
}
return true;
}
else {
// the required parameters were not present
return false;
}
}

events.onEvent('situationProcess', constants.eventType('Sig')).listen();
events.onEvent('situationProcess', constants.eventType('SigUpdate')).listen();

You might also like