The Now Platform® Washington DC release is live. Watch now!
on 08-16-2019 07:41 PM
Recently we published an article on discovering new resource types in AWS (link here :https://community.servicenow.com/community?id=community_article&sys_id=2cdb9d69db47734814d6fb2439961...) . This is the sibling article and deals with discovering new resource types in Azure.
All things applicable to that article are applicable here. Only change is that we need to refer to Azure APIs and documents in place of AWS.
Cloud Provider API can be got from Azure API like this https://docs.microsoft.com/en-us/rest/api/compute/virtualmachines/list.
We need the following for making a proper call.
If you have the above listed parameters, we can make any discovery call.
Sample Response
In this exercise we will discover and populate networks. We will set the name, object_id and state.
The above image shows the different important pieces that are needed for making a success list call for network.
Network CMDB Model:
Adding new Resource Type Discovery:
var metadata = {
"datasourceName": "Discover Azure Networks",// a unique name
"ciClass": "cmdb_ci_network", // comes from CMDB
"dependentOn" : "cmdb_ci_azure_datacenter", // dependent field used for identification. In this case we need to get the location.
"dependentOnSourceField" : "location",// response has a field called 'location'. we use it to map it to the datacenter.
"fields": [
{
"sourceField": "name",
"ciClassField": "name"
},
{
"isIdentification": true,
"sourceField": "id",
"ciClassField": "object_id"
},
{
"fixed_value": "available",
"attrMappingType" : "fixed",
"ciClassField": "state"
}
]
};
new sn_cmp.AzureDiscoveryStepCreator().addResourceTypeDiscovery(
'/subscriptions/${subscriptionId}/resourceGroups/${resourceGroupName}/providers/Microsoft.Network', // the path
'Microsoft.Network/virtualNetworks', // resource type
'2019-06-01', // versionDefault
'', // JSON Path if we are interested in a subset of data. In this case we want all.
metadata //mapping metadata
);
In the above sample, just the name, state and object_id are populated. More columns and CI relations can also be populated using the same mechanism.
The script include 'AzureDiscoveryStepCreator' is the script we will use to persist the mapping as well as create the discovery operation step to discover the resource type network. This script include has a method called 'addResourceTypeDiscovery'. This takes in the response mappings as well as the API information as described in the scriptlet above.
Run the above script in the background script and it will do the needful and you can discover from AWS via the cloud account or a service account.
To see if the data is properly set, you can do the following.
The Cloud API call with all pertinent information passed as parameters.
The response processing:
You woul see that the step has a association with a standard Azure Discover call and a GenericListProcessor for the response processing. All things are wired for you automatically.
That’s it. You are done. You can do a ‘Discover Now’ in the Cloud Account and your discovery will be running fine.
The same CAPI call can be used for discovering any Azure resource type. You can rinse and repeat for discovering other Azure resource types now.
The updateset for the Azure Discovery Common Cloud API is here :
Hi,
I've tried doing this for an ExpressRoute Circuit but the resource doesn't get discovered.
It says "West Europe -- Azure Datacenter.Discover.Azure Datacenter.Discover Microsoft.Network/expressRouteCircuits -- Completed" in the discovery log so it seems like I've done it correctly though..
I ran the the following script in Xplore after committing the updateset and creating the CI class:
var metadata = {
"datasourceName": "Discover Azure Networks",// a unique name
"ciClass": "u_cmdb_ci_expressroute_circuit", // comes from CMDB
"dependentOn" : "cmdb_ci_azure_datacenter", // dependent field used for identification. In this case we need to get the location.
"dependentOnSourceField" : "location",// response has a field called 'location'. we use it to map it to the datacenter.
"fields": [
{
"sourceField": "name",
"ciClassField": "name"
},
{
"isIdentification": true,
"sourceField": "id",
"ciClassField": "object_id"
},
{
"fixed_value": "available",
"attrMappingType" : "fixed",
"ciClassField": "state"
}
]
};
new sn_cmp.AzureDiscoveryStepCreator().addResourceTypeDiscovery(
'/subscriptions/${subscriptionId}/resourceGroups/${resourceGroupName}/providers/Microsoft.Network', // the path
'Microsoft.Network/expressRouteCircuits', // resource type
'2019-09-01', // versionDefault
'', // JSON Path if we are interested in a subset of data. In this case we want all.
metadata //mapping metadata
);
I've tried making the REST API in postman to make sure that the App Registration works and i get the list of resources returned.
Does the above script look correct? Anything else I might have done wrong?
Thanks,
Manfred
Hi Manfred,
How was the CI class for express route created ? Did you extend it from an existing class ? Basically looking for a column 'object_id'. If it was a class you created from scratch, that column with name is needed.
Also did you see the call going in the cloud api trail?
Also look in the cloud trail as well.
regards
ashok
Hi Ashok,
I am getting the below error, could please guide me on how can we troubleshoot this error?
Is something we can do from our end ?
Please Note : When I tried searching for the 'sys_id' No record were found for getLdcAndServiceAccount('sys_id')
Failed to parse the output of new CMPCIRelationshipUtil().getLdcAndServiceAccount('sys_id'), exception: : com.fasterxml.jackson.databind.exc.MismatchedInputException: No content to map due to end-of-input
at [Source: (String)""; line: 1, column: 0]: com.fasterxml.jackson.databind.exc.MismatchedInputException.from(MismatchedInputException.java:59)
com.fasterxml.jackson.databind.ObjectMapper._initForReading(ObjectMapper.java:4133)
com.fasterxml.jackson.databind.ObjectMapper._readMapAndClose(ObjectMapper.java:3988)
com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:2992)
com.snc.cloud.mgmt.modules.svccatalog.service.processor.CIRelationShipIdentifier.identifyDatacenter(CIRelationShipIdentifier.java:93)
com.snc.cloud.mgmt.modules.svccatalog.service.impl.ResourceOperationProcessor.parseOperation(ResourceOperationProcessor.java:97)
com.snc.cloud.mgmt.modules.svccatalog.service.impl.CloudOrchestrationServiceImpl.orchestrate(CloudOrchestrationServiceImpl.java:263)
com.snc.cloud.mgmt.modules.svccatalog.service.impl.OrderServiceImpl.submitOrder(OrderServiceImpl.java:114)
com.snc.cloud.mgmt.modules.svccatalog.scriptinterface.OrderServiceScript.jsFunction_submitOrderInDomain(OrderServiceScript.java:92)
sun.reflect.GeneratedMethodAccessor1891.invoke(Unknown Source)
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
java.lang.reflect.Method.invoke(Method.java:498)
org.mozilla.javascript.MemberBox.invoke(MemberBox.java:138)
org.mozilla.javascript.FunctionObject.doInvoke(FunctionObject.java:670)
org.mozilla.javascript.FunctionObject.call(FunctionObject.java:614)
org.mozilla.javascript.ScriptRuntime.doCall(ScriptRuntime.java:2582)
org.mozilla.javascript.optimizer.OptRuntime.call2(OptRuntime.java:42)
org.mozilla.javascript.gen.sys_script_include_sys_id_script_150088._c_anonymous_6(sys_script_include.sys_id of Discoe:190)
org.mozilla.javascript.gen.sys_script_include_AzureAlertHandlerV2_script_150088.call(sys_script_include.AzureAlertHandlerV2.script)
org.mozilla.javascript.ScriptRuntime.doCall2(ScriptRuntime.java:2651)
org.mozilla.javascript.ScriptRuntime.doCall(ScriptRuntime.java:2590)
org.mozilla.javascript.optimizer.OptRuntime.callN(OptRuntime.java:52)
org.mozilla.javascript.gen.sys_script_include_AzureAlertHandlerV2_script_150088._c_anonymous_3(sys_script_include.AzureAlertHandlerV2.script:120)
org.mozilla.javascript.gen.sys_script_include_AzureAlertHandlerV2_script_150088.call(sys_script_include.AzureAlertHandlerV2.script)
org.mozilla.javascript.ScriptRuntime.doCall2(ScriptRuntime.java:2651)
org.mozilla.javascript.ScriptRuntime.doCall(ScriptRuntime.java:2590)
Any hints or suggestions will be helpful.
Thanks in advance!
Meenal
Hi Brian,
Thank you for your response.
I tried checking with "Interface name" = "Azure Disco Common Interface" and method name = "Discover". this doesn't gives me any data.
Best Regards,
Meenal
Do you see any CAPI trail records in the error state that look like it might be related?
You can also check the Cloud Orchestration Trail (sn_cmp_cloud_trail) to see if there are any relevant errors there.
Hi Brian,
Thank you for your response.
I tried checking error on CAPI trail no luck.
But I also tried checking OOB script include which is coming in error log.
I have pasted the function below in which I'm getting this error as per above logs.
Script Include name - CMPCIRelationshipUtil
getLdcAndServiceAccount: function (ciId) {
gs.info("Debugging for CI: " + ciId);
// if ciId is nil, it means discovery on service account, exiting early
if(gs.nil(ciId))
return null;
var response = this._getRelationshipGraph(ciId,false);
gs.info('Graph :'+JSON.stringify(response));
var result = this._buildResults(response);
if (result!=null && result.trim() != '') {
return result;
} else {
response = this._getRelationshipGraph(ciId, true);
gs.info('Graph :'+JSON.stringify(response));
return this._buildResults(response);
}
},
Thank you.
Best Regards,
Meenal