The Approval node is used to define the approval request to execute the change.
You can define two types of approval requests:
▪NetBrain — define and complete an approval workflow in the system.
▪External — integrate with an external ticket system and approve the task in the external system.
Tip: Before using this feature, ensure that you have sufficient privilege. See Access Controls for more details.
1.Select the Planning node in the runbook.
2.In the Approval pane, select NetBrain in the Approval System field.
3.Click Approval Request, and adjust the following settings in the Request Approval dialog.
1)Select an approver from the Approver drop-down list.
Tip: If the user you want to select is not on the list, contact your NetBrain administrator to assign the required privilege to the user.
2)In the Comment field, enter some comments about the approval request.
3)Click Submit. After the request is submitted, the designated approver will receive an email (if the email setting is configured) and system notification.
1.Select the Planning node in the runbook.
2.In the Approval pane, select External in the Approval System field.
Note: If the External option is disabled, see Approval Settings for how to adjust the approval option.
3.Click Copy to copy and paste the runbook ID. The ID will be used to link with a ticket in an external system, thus building a connection with the Approval node in the external system for status synchronization.
4.Create a change ticket in the external system and customize two fields in the ticket to save the Change Management ID and returned NetBrain URL.
5.Create a business rule to define ticket and network change task status mapping and API calls in the external system. The rule mainly covers the following components:
▪How to access your domain.
▪Map ticket state and Change Management status.
▪Bind ticket ID to Change Management ID.
▪Call NetBrain API to Set Change Management Status when ticket state changes.
Example: Define Status Mapping and API Calls in ServiceNow.
/**
* ServiceNow Script Example, Please follow this script
*
*/
(function executeRule(current, previous /*null when async*/) {
var NB_API_PREFIX = 'http://your web API server address/ServicesAPI/API/V1/';
// login to get token & logout
var tokenEndPoint = NB_API_PREFIX + 'Session';
var tenantDomainEndPoint = NB_API_PREFIX + 'Session/CurrentDomain';
// credential to log into netbrain
var credential = {
username: 'admin',
password: 'admin'
};
var tenantDomain = { tenantId: 'xxx', domainId: 'xxx' };
// api time out default is 10 seconds
var API_TIME_OUT = 10 * 1000;
// store the netbrain api token
var nbToken = '';
// **********************
var vendor = 'ServiceNow';
var stateMapping = {
'not requested': 0, // planning
'requested': 1, // pending
'approved': 2,
'rejected': 3
};
/**
* Request the token
* @return hasToken: bool
*
*/
function login() {
var request = newRequest(tokenEndPoint, 'POST', credential);
try {
gs.info('send request to netbrain, get the token'); //
var response = request.execute();
var responseBody = response.getBody();
var obj = new JSON.parse(responseBody);
nbToken = obj.token;
return nbToken.length > 0;
} catch (ex) {
// todo handle get token failed exception where to check this error msg
gs.error('get netbrain token failed.');
gs.error(ex.getMessage());
return false;
}
return false;
}
/**
* logout netbrain, remove token
* @return
* @constructor
*/
function logout() {
var body = {
token: nbToken
};
var request = newRequest(tokenEndPoint, 'DELETE', body);
try {
gs.info('logout netbrain.');
request.execute();
gs.info('logout netbrain success.');
} catch (ex) {
gs.error('get netbrain token failed.');
gs.error(ex.getMessage()); // should retry?
}
}
function addActivity(message) {
current.work_notes = message;
current.update();
}
/**
* Request to set tenant & domain
* @return success: bool
*
*/
function setTenantDomain() {
var request = newRequest(tenantDomainEndPoint, 'PUT', tenantDomain);
try {
gs.info('set tenant & domain info.');
var response = request.execute();
var responseBody = response.getBody();
var obj = new JSON.parse(responseBody);
return true;
} catch (ex) {
gs.error('set tenant & domain failed.');
gs.error(ex.getMessage()); // should retry?
return false;
}
return false;
}
/**
* make a http call to netbrain to bind change request id to a cm runbook id
* @return
*
*/
function apiCMBinding() {
var ticketId = current.getValue('sys_id');
var runbookId = current.getValue('netbrain_cm_id');// this might be different for different customer
var ticketName = current.getValue('number'); // this might be different for different customer
var endPoint = NB_API_PREFIX + 'CM/Binding';
var snState = current.getValue('approval');
if (stateMapping[snState] == null) {
gs.error('cannot find the correspond state from netbrain.');
return;
}
var postData = {
runbookId: runbookId,
ticketId: ticketId,
vendor: vendor,
ticketName: ticketName,
state: stateMapping[snState]
};
var request = newRequest(endPoint, 'POST', postData);
try {
gs.info('send change management binding request.');
var response = request.execute();
var responseBody = response.getBody();
var obj = new JSON.parse(responseBody);
if (obj.statusCode == 0) {
gs.info('change management binding to ' + runbookId + ' success.');
addActivity('change management binding to ' + runbookId + ' success.');
} else {
gs.info(obj.statusDescription);
// please change it to a proper msg, and this message is going to display on service now page
gs.addErrorMessage('binding Failed: ' + obj.statusDescription);
addActivity('binding Failed: ' + obj.statusDescription);
}
} catch (ex) {
gs.error('change management binding failed.');
gs.error(ex.getMessage()); // should retry?
gs.addErrorMessage('binding Failed: ' + ex.getMessage());
addActivity('binding Failed: ' + ex.getMessage());
}
}
/**
* make a http call to netbrain to set cm runbook approval state
*/
function apiUpdateCMApprovalState() {
var ticketId = current.getValue('sys_id'); // this might be different for different customer
var runbookId = current.getValue('netbrain_cm_id');// this might be different for different customer
var endPoint = NB_API_PREFIX + 'CM/approval/state';
var ticketName = current.getValue('number'); // this might be different for different customer
var snState = current.getValue('approval');
if (stateMapping[snState] == null) {
gs.error('cannot find the correspond state from netbrain.');
return;
}
var postData = {
runbookId: runbookId,
ticketId: ticketId,
vendor: vendor,
ticketName: ticketName,
state: stateMapping[snState]
};
var request = newRequest(endPoint, 'POST', postData);
try {
gs.info('set change management state.');
var response = request.execute();
var responseBody = response.getBody();
var obj = new JSON.parse(responseBody);
if (obj.statusCode == 0) {
var msg = 'set change management(' + runbookId + ') to state ' + snState + ' success.'
gs.info(msg);
addActivity(msg);
} else {
gs.info(obj.statusDescription);
gs.addErrorMessage('update approval failed: ' + obj.statusDescription);
addActivity('update approval failed: ' + obj.statusDescription);
}
} catch (ex) {
gs.error('set change management state failed.');
gs.error(ex.getMessage());
gs.addErrorMessage('Error: ' + ex.getMessage());
addActivity('Error: ' + ex.getMessage());
}
}
function newRequest(url, method, data) {
var request = new sn_ws.RESTMessageV2();
request.setEndpoint(url);
request.setHttpMethod(method);
request.setRequestBody(JSON.stringify(data));
request.setRequestHeader('Accept', 'application/json');
request.setRequestHeader('Content-Type', 'application/json');
request.setRequestHeader('token', nbToken);
request.setHttpTimeout(API_TIME_OUT);
return request;
}
/**
* update a value of service now
*/
function updateColumnValue(table, primaryKey, primaryVal, targetColumn, targetVal) {
var gr = new GlideRecord(table);
gr.addQuery(primaryKey, primaryVal);
gr.query();
if (gr.next()) {
gr.setValue(targetColumn, targetVal);
gr.update();
}
}
/**
* make a http call to netbrain to binding change request id to a cm runbook id
*/
function main() {
var hasToken = login();
if (hasToken) {
gs.debug('login success.');
if (setTenantDomain()) {
// business logic
apiCMBinding();
apiUpdateCMApprovalState();
}
logout();
} else {
gs.info('login failed, quit now...');
}
}
main(); // run
})(current, previous);
1.Log in to the Domain Management page.
2.In the Domain Management page, click Operations > Domain Settings > Change Management Settings from the quick access toolbar.
3.On the Change Management Settings tab, enable the approval method you want to use.
4.Click Submit.