The Now Platform® Washington DC release is live. Watch now!

Help
cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 
Ashok Madhavan1
ServiceNow Employee
ServiceNow Employee

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.

  • Location - the location where to discover from
  • SubscriptionID - This can be sent via ${parameter.CloudServiceAccountId}
  • pathDefault - the path to get to the resource like /subscriptions/${subscriptionId}/resourceGroups/${resourceGroupName}/providers/Microsoft.Network
  • resourceType - the resource type like Microsoft.Network/virtualNetworks
  • versionDefault - the apiVersion of the API like 2016-03-30

 If you have the above listed parameters, we can make any discovery call.

find_real_file.png

 

Sample Response 

find_real_file.png

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:

find_real_file.png

 

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.

  • Get to Cloud Admin Portal ==> Design ==> Resource Block ==> Azure Datacenter ==> Operations ==> Discovery Interface ==> Discover ==> Steps
  • You will see the a set of steps. Look for the step which you created. The name would be 'Discover '+ $resourceType.

The Cloud API call with all pertinent information passed as parameters.

find_real_file.png 

 The response processing:

find_real_file.png

 

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 :

https://developer.servicenow.com/app.do#!/share/contents/4708895_cmp_azure_discovery_extension_mecha...

 

Comments
Manfred St_l
Kilo Explorer

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

 

Ashok Madhavan1
ServiceNow Employee
ServiceNow Employee

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 

 

Meenal Gharat
Mega Guru

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

brian_quinn
ServiceNow Employee
ServiceNow Employee

@Meenal Gharat I would start by looking at the Cloud API Trail.  I believe you will need to search for "Interface name" = "Azure Disco Common Interface" and method name = "Discover".  If you open one of the records, there will be a related list for "CAPI Trail Logs".  Take a look at the route_result record and see if it looks like a valid response from Azure with JSON data for the resources.

Meenal Gharat
Mega Guru

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

brian_quinn
ServiceNow Employee
ServiceNow Employee

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.  

Meenal Gharat
Mega Guru

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

Version history
Last update:
‎08-16-2019 07:41 PM
Updated by: