Name
sn_grc.GRCCMDBQueryIntegrationBase
Description
This script include contains functionalities to integrate with CMDB query builder for entity scoping.
Script
var GRCCMDBQueryIntegrationBase = Class.create();
GRCCMDBQueryIntegrationBase.prototype = {
cmdbQueryUtils: new global.CMDBQueryUtils(),
initialize: function() {
var queryResults = null,
queryResultsWithIO = null;
},
findConfigurationItems: function(hashValue, table, queryId, filters, isEncodedQuery) {
var cmdbQueryResults = {
ciWithoutIORelations: null,
ciWithIORelations: null,
result: false
},
finalResults = null;
try {
if (gs.nil(table) || gs.nil(queryId)) {
return cmdbQueryResults;
}
var existingCmdbGroupApiResponse = this._getExistingQueryResults(queryId, hashValue);
if (!gs.nil(existingCmdbGroupApiResponse)) {
cmdbQueryResults.result = true;
cmdbQueryResults.ciWithoutIORelations = existingCmdbGroupApiResponse.results;
cmdbQueryResults.ciWithIORelations = this.queryResultsWithIO[hashValue] ? this.queryResultsWithIO[hashValue] : null;
} else {
finalResults = this._getResultsFromCMDB(table, queryId, null, filters, isEncodedQuery, false, hashValue);
cmdbQueryResults.result = finalResults.result;
cmdbQueryResults.ciWithoutIORelations = finalResults.ciWithoutIORelations;
cmdbQueryResults.ciWithIORelations = finalResults.ciWithIORelations ? finalResults.ciWithIORelations : null;
}
} catch (ex) {
gs.error(gs.getMessage('Exception occured from sn_grc.GRCCMDBQueryIntegrationBase.findConfigurationItems: {0}', ex.toString()));
}
return cmdbQueryResults;
},
getCMDBQueryNodes: function(queryId) {
return this._getCMDBQueryNodes(queryId);
},
_getExistingQueryResults: function(queryId, entityFilterId) {
if (gs.nil(this.queryResults) || this.queryResults.length == 0) return null;
for (var i = 0; i < this.queryResults.length; i++) {
if (queryId == this.queryResults[i].queryId) {
for (var j = 0; j < this.queryResults[i].results.length; j++) {
if (entityFilterId == this.queryResults[i].results[j].hash) {
return this.queryResults[i].results[j];
}
}
}
}
},
_getResultsFromCMDB: function(table, queryId, configurationItems, filters, isEncodedQuery, isIOMappingRequired, hashValue) {
var resultsResponse = {
result: false
};
var queryDetails = this._getQueryWithFilters(queryId, filters, isEncodedQuery);
var isNewApiAvailable = !gs.nil(this.cmdbQueryUtils.getCMDBQueryExecutionDetails);
if (!gs.nil(queryDetails.queryJson)) {
var cmdbResponse = isNewApiAvailable ? this._invokeCMDBNewAPI(queryDetails, hashValue, table) : this._invokeCMDB(queryDetails, hashValue);
resultsResponse.result = cmdbResponse.result;
var resultCis = (cmdbResponse.result && !gs.nil(cmdbResponse.outputCis)) ? isNewApiAvailable ? Object.keys(cmdbResponse.outputCis) : JSON.parse(cmdbResponse.outputCis) : null;
cmdbResponse.newGroupId ? this._associateCmdbGroupToEntityFilter(hashValue, cmdbResponse.newGroupId) : '';
if (!gs.nil(resultCis) && resultCis.length > 0) {
var queryIO = {
hash: hashValue,
resultTable: this._getQueryResultTable(cmdbResponse.newQueryId),
queryName: cmdbResponse.newQueryName,
results: resultCis
};
if (gs.nil(this.queryResults)) this.queryResults = [];
var queryResultsAvailable = false;
for (var i = 0; i < this.queryResults.length; i++) {
if (queryId == this.queryResults[i].queryId) {
var existingFiltersAvailable = false;
for (var j = 0; j < this.queryResults[i].results.length; j++) {
if (queryIO.hash == this.queryResults[i].results[j].hash) {
this.queryResults[i].results[j] = queryIO;
existingFiltersAvailable = true;
break;
}
}
if (!existingFiltersAvailable) {
this.queryResults[i].results.push(queryIO);
}
queryResultsAvailable = true;
break;
}
}
if (!queryResultsAvailable) {
var queryResult = {
queryId: queryId,
results: [queryIO]
};
this.queryResults.push(queryResult);
}
if (isNewApiAvailable) {
if (gs.nil(this.queryResultsWithIO)) this.queryResultsWithIO = {};
this.queryResultsWithIO[hashValue] = cmdbResponse.outputCis;
resultsResponse.ciWithIORelations = cmdbResponse.outputCis;
}
resultsResponse.ciWithoutIORelations = resultCis;
}
}
return resultsResponse;
},
_getExistingResultTable: function(queryId, hashValue) {
var table = null;
if (!gs.nil(this.queryResults) && this.queryResults.length > 0) {
for (var i = 0; i < this.queryResults.length; i++) {
if (queryId == this.queryResults[i].queryId) {
for (var j = 0; j < this.queryResults[i].results.length; j++) {
if (hashValue == this.queryResults[i].results[j].hash) {
table = this.queryResults[i].results[j].resultTable;
break;
}
}
}
}
}
return table;
},
_getCMDBQueryNodes: function(queryId) {
var nodes = [];
var queryDetails = this._getSelectedQueryDetails(queryId);
if (!gs.nil(queryDetails)) {
var jsonObject = JSON.parse(queryDetails.queryJson);
if (jsonObject.nodes.length > 0) {
var ioTableName = 'cmdb_ci_information_object';
for (var i = 0; i < jsonObject.nodes.length; i++) {
var node = {};
node.isStartNode = jsonObject.nodes[i].isStartNode;
node.nodeId = jsonObject.nodes[i].nodeId;
node.table = jsonObject.nodes[i].ci_type;
node.name = jsonObject.nodes[i].ci_type_label;
node.isEndNode = false;
if (!node.isStartNode) {
if (node.table == ioTableName) {
node.isEndNode = true;
for (var j = 0; j < jsonObject.edges.length; j++) {
if (node.nodeId == jsonObject.edges[j].from) {
node.isEndNode = false;
break;
}
}
}
}
nodes.push(node);
}
}
}
return nodes;
},
_getEncodedQueryForGivenCis: function(table, sysIds, ioFilters) {
var encodedQuery = this._getEncodedQuery(ioFilters, false);
if (gs.nil(encodedQuery)) {
encodedQuery = {};
}
encodedQuery[table] = 'sys_idIN' + sysIds.join(',');
return encodedQuery;
},
_invokeCMDBNewAPI: function(queryDetails, hashValue, table) {
var queryRecordDetails = '',
newQueryId = '';
var entityTypeFilter = new GlideRecord('sn_grc_enrichment_query');
if (!entityTypeFilter.get(hashValue)) return;
var cmdbQueryGr = entityTypeFilter.final_query;
cmdbQueryGr = cmdbQueryGr.nil() ? '' : cmdbQueryGr.getRefRecord();
if (cmdbQueryGr && cmdbQueryGr.isValidRecord()) {
queryRecordDetails = [cmdbQueryGr.getUniqueValue(), cmdbQueryGr.getValue('name')];
}
if (gs.nil(queryRecordDetails)) {
queryRecordDetails = this._createCMDBQuery(queryDetails);
newQueryId = queryRecordDetails[0];
entityTypeFilter.setValue('final_query', newQueryId);
entityTypeFilter.update();
} else {
newQueryId = queryRecordDetails[0];
this._updateCMDBQuery(newQueryId, queryDetails);
}
if (gs.nil(queryRecordDetails) || queryRecordDetails.length < 2) return null;
var response = this._executeQueryForResults(queryRecordDetails[1]);
var ciIOMappings = this._getDataFromResultTable(newQueryId, response.resultTable);
return {
result: response.isSuccess,
outputCis: ciIOMappings,
newQueryId: newQueryId,
newQueryName: queryRecordDetails[1]
};
},
_invokeCMDB: function(queryDetails, hashValue) {
var groupId = '',
queryRecordDetails = null,
newQueryId = '';
var grEntityFilterToCmdbGroup = new GlideRecord("sn_grc_m2m_enrichment_query_cmdb_group");
grEntityFilterToCmdbGroup.addQuery('entity_filter', hashValue);
grEntityFilterToCmdbGroup.query();
if (grEntityFilterToCmdbGroup.next()) {
groupId = grEntityFilterToCmdbGroup.getValue('cmdb_group');
queryRecordDetails = this._getExistingCMDBQueryDetails(groupId);
} else {
groupId = this._createCMDBGroup();
}
if (gs.nil(queryRecordDetails)) {
queryRecordDetails = this._createCMDBQuery(queryDetails);
newQueryId = queryRecordDetails[0];
this._createMappingBetweenGroupAndQuery(groupId, newQueryId);
} else {
newQueryId = queryRecordDetails[0];
this._updateCMDBQuery(queryRecordDetails[0], queryDetails);
}
if (gs.nil(queryRecordDetails) || queryRecordDetails.length < 2) return null;
var response = this._executeCMDBGroup(groupId);
return {
result: response.result,
outputCis: response.outputCis,
newGroupId: groupId,
newQueryId: newQueryId,
newQueryName: queryRecordDetails[1]
};
},
_updateCMDBQuery: function(queryId, latestQueryDetails) {
var gr = new GlideRecord('qb_saved_query');
if (gr.get(queryId)) {
gr.setValue("query", latestQueryDetails.queryJson);
gr.update();
}
},
_getExistingCMDBQueryDetails: function(groupId) {
var grGroupToQueryMapper = new GlideRecord('cmdb_group_contains_qb_query');
grGroupToQueryMapper.addQuery('group', groupId);
grGroupToQueryMapper.query();
while (grGroupToQueryMapper.next()) {
var grCmdbQuery = new GlideRecord('qb_saved_query');
if (grCmdbQuery.get(grGroupToQueryMapper.getValue('qb_query'))) {
return [grCmdbQuery.getUniqueValue(), grCmdbQuery.getValue('name')];
}
}
return null;
},
_getQueryWithFilters: function(queryId, filters, isEncodedQuery) {
var requiredDetailsForNewQuery = {
queryJson: '',
resultTableName: ''
};
var selectedQueryDetails = this._getSelectedQueryDetails(queryId);
if (gs.nil(selectedQueryDetails.queryJson)) {
return requiredDetailsForNewQuery;
}
requiredDetailsForNewQuery.resultTableName = selectedQueryDetails.resultTableName;
var encodedQuery = this._getEncodedQuery(filters, isEncodedQuery);
requiredDetailsForNewQuery.queryJson = selectedQueryDetails.queryJson;
if (!gs.nil(encodedQuery)) {
var nodeKeys = Object.keys(encodedQuery);
if (nodeKeys.length > 0) {
var jsonObject = JSON.parse(selectedQueryDetails.queryJson);
for (var j = 0; j < jsonObject.nodes.length; j++) {
if (!gs.nil(encodedQuery[jsonObject.nodes[j].ci_type])) {
jsonObject.nodes[j].filters_attrib = encodedQuery[jsonObject.nodes[j].ci_type];
jsonObject.nodes[j].applied_filters = encodedQuery[jsonObject.nodes[j].ci_type];
}
}
requiredDetailsForNewQuery.queryJson = JSON.stringify(jsonObject);
}
}
return requiredDetailsForNewQuery;
},
_createCMDBGroup: function() {
var groupName = this._guid();
var grCmdbGroup = new GlideRecord('cmdb_group');
grCmdbGroup.initialize();
grCmdbGroup.setValue('group_name', groupName);
var groupId = grCmdbGroup.insert();
return groupId;
},
_createCMDBQuery: function(queryDetails) {
var newQueryName = 'GRC_' + this._guid();
var gr = new GlideRecord('qb_saved_query');
gr.initialize();
gr.setValue('name', newQueryName);
gr.setValue('query', queryDetails.queryJson);
var querySysId = gr.insert();
return [querySysId, newQueryName];
},
_getDataFromResultTable: function(queryId, resultTableName) {
if (gs.nil(resultTableName) || !gs.tableExists(resultTableName)) return null;
var queryResultTableFields = this._getCMDBQueryFieldNames(queryId);
if (gs.nil(queryResultTableFields)) return null;
var startNodeField = queryResultTableFields['start_node'];
var ioFields = queryResultTableFields['information_objects'];
var results = {};
var currentRecIndex = 0,
offset = 1000;
var resultsGr = new GlideRecord(resultTableName);
resultsGr.chooseWindow(currentRecIndex, currentRecIndex + offset, false);
resultsGr.query();
while (resultsGr.hasNext()) {
while (resultsGr.next()) {
currentRecIndex++;
var startNodeValue = resultsGr.getValue(startNodeField);
results[startNodeValue] = results[startNodeValue] ? results[startNodeValue] : {};
for (var key in ioFields) {
if (ioFields[key] && !gs.nil(resultsGr.getValue(ioFields[key])))
results[startNodeValue][resultsGr.getValue(ioFields[key])] = true;
}
}
resultsGr.initialize();
resultsGr.chooseWindow(currentRecIndex, currentRecIndex + offset, false);
resultsGr.query();
}
return results;
},
_executeQueryForResults: function(queryName) {
var globalAPIResponse = {
error: {},
resultTable: '',
isSuccess: false
};
var executionResultsResponse = this.cmdbQueryUtils.getCMDBQueryExecutionDetails(queryName);
if (!gs.nil(executionResultsResponse)) {
executionResultsResponse = JSON.parse(executionResultsResponse);
switch (executionResultsResponse.status) {
case 'COMPLETE':
globalAPIResponse.isSuccess = true;
globalAPIResponse.resultTable = executionResultsResponse.table_name;
break;
case 'FAILED':
globalAPIResponse.error = executionResultsResponse.error;
globalAPIResponse.isSuccess = false;
gs.error('sn_grc.GRCCMDBQueryIntegrationBase.getAssociationsFromQueryResults: CMDB Query execution failed. Error: ' + JSON.stringify(globalAPIResponse.error));
break;
case 'TIME_OUT':
case 'MAX_LIMIT':
globalAPIResponse.isSuccess = false;
gs.error('sn_grc.GRCCMDBQueryIntegrationBase.getAssociationsFromQueryResults: CMDB Query execution failed. Error: ' + JSON.stringify(executionResultsResponse.status));
break;
}
}
return globalAPIResponse;
},
_createMappingBetweenGroupAndQuery: function(groupId, newQueryId) {
var gr = new GlideRecord('cmdb_group_contains_qb_query');
gr.initialize();
gr.setValue('group', groupId);
gr.setValue('qb_query', newQueryId);
var sysId = gr.insert();
return sysId;
},
_executeCMDBGroup: function(groupId) {
var cmdbResponse = {
outputCis: [],
result: false
};
try {
var response = sn_cmdbgroup.CMDBGroupAPI.getAllCIFromQueryBuilder(groupId, false, false);
if (!gs.nil(response)) {
var responseObj = JSON.parse(response);
cmdbResponse.result = responseObj.result;
if (responseObj.result && !gs.nil(responseObj.idList)) {
cmdbResponse.outputCis = JSON.stringify(responseObj.idList);
}
}
} catch (ex) {
gs.error('Error occured from sn_grc.GRCCMDBQueryIntegrationBase._executeCMDBGroup {0}', ex.toString());
}
return cmdbResponse;
},
_associateCmdbGroupToEntityFilter: function(entityFilterId, groupId) {
if (!gs.nil(entityFilterId) && !gs.nil(groupId)) {
new GRCUtils().associateCmdbGroupToEntityFilter(entityFilterId, groupId);
}
},
_getSelectedQueryDetails: function(queryId) {
var requiredDetails = {
queryJson: '',
resultTableName: ''
};
var glideRecord = new GlideRecord('qb_saved_query');
glideRecord.addQuery('sys_id', queryId);
glideRecord.query();
if (glideRecord.next()) {
requiredDetails.queryJson = glideRecord.getValue('query');
requiredDetails.resultTableName = glideRecord.getValue('result_table');
}
return requiredDetails;
},
_getEncodedQuery: function(filters, isEncodedQuery) {
if (gs.nil(filters) || isEncodedQuery) return filters;
var encodedQuery = 'sys_idIN' + filters;
var encodedQueryFilters = {
cmdb_ci_information_object: encodedQuery
};
return encodedQueryFilters;
},
_getPaginations: function(largeArray) {
var index = 0;
var chunk_size = 100;
var tempArray = [];
for (index = 0; index < largeArray.length; index += chunk_size) {
var myChunk = largeArray.slice(index, index + chunk_size);
tempArray.push(myChunk);
}
return tempArray;
},
_queryTable: function(table, sysIds, requiredField) {
var requiredData = [];
var glideRecord = new GlideRecord(table);
glideRecord.addQuery('sys_id', 'IN', sysIds);
glideRecord.query();
while (glideRecord.next()) {
requiredData.push(glideRecord.getValue(requiredField));
}
return requiredData;
},
_getQueryResultTable: function(newQueryId) {
var name = '';
var glideRecord = new GlideRecord('cmdb_qb_table_mapping');
glideRecord.addQuery('query', newQueryId);
glideRecord.setLimit(1);
glideRecord.query();
if (glideRecord.next()) {
name = glideRecord.getValue('table_name');
}
return name;
},
_getCMDBQueryFieldNames: function(queryId) {
var fields = {
'start_node': '',
'information_objects': {}
};
var savedQueryGr = new GlideRecord('qb_saved_query');
if (!savedQueryGr.get(queryId)) return;
var query = JSON.parse(savedQueryGr.getValue('query'));
var queryNodes = query['nodes'];
var queryEdges = query['edges'];
for (var i = 0; i < queryNodes.length; i++) {
if (queryNodes[i].isStartNode) {
fields['start_node'] = 'u_' + queryNodes[i].name.toLowerCase().replaceAll(' ', '_');
continue;
}
if (queryNodes[i].ci_type == 'cmdb_ci_information_object')
fields['information_objects'][queryNodes[i].nodeId] = 'u_' + queryNodes[i].name.toLowerCase().replaceAll(' ', '_');
}
for (var i = 0; i < queryEdges.length; i++) {
if (fields['information_objects'][queryEdges[i].from])
delete fields['information_objects'][queryEdges[i].from];
}
return fields;
},
_guid: function(len) {
var buf = [],
chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789',
charlen = chars.length,
length = len || 32;
for (var i = 0; i < length; i++) {
buf[i] = chars.charAt(Math.floor(Math.random() * charlen));
}
return buf.join('');
},
type: 'GRCCMDBQueryIntegrationBase'
};
Sys ID
13b3a4be53c364105468ddeeff7b1263