CMDB Identification & Reconciliation and Domain Separation

Jon G
Kilo Expert

I'm trying to understand the logic behind the way domain separation was implemented into Identification and Reconciliation, and how to get around one of the poor design choices.

In most areas of the system, domain separation follows certain rules about what can and cannot be accessed by certain users.  For example, in my domain, I can see data in all other domains.  However, users in a child domain can only see data within their domain.  This is the standard domain separation logic in almost every area of the system.

We are a services provider, and so we use domain separation to ensure our clients cannot access areas of the system outside of their domain.  Each company has its own domain.

In Identification and Reconciliation, the engine uses the domain of the logged in user for any matching.  I 100% understand the logic behind only wanting to match devices in the same domain - and in fact, I would want in that way.  A device from organization A should never be matched against a device in organization B.  I'm following the decision here so far.

As part of the services that we offer, we do monitoring on our clients' networks.  I'm trying to import all of our monitored devices into CMDB.  As part of the import, I have the company name as an element of each device that is imported.

Here's where the process breaks down: In any other area of the system, if I perform an import as my user that can see into other domains, and provide a company name, that device is imported into that company's domain.  This is correct behavior - the device ends up in the correct domain. So far so good.

However, the logic of the identification and reconciliation engine observes the logged-in user's domain exactly and doesn't seem to respect domain visibility permissions and hierarchy.  If the device CI is in my domain, it will match.  If the device is in any other domain, it will not match an imported CI against an existing CI even though I am providing the company name, and even though the device ends up in the correct domain.

I've tried importing as system admin, and at the global domain level as well.  Neither achieves the desired results.  I've also tried running my import script in a scheduled job and letting the job run as "system" - still does not work.

The documentation outlines specifically that:

  • Domain IDs do not need to be explicitly sent in the input payload of the identification engine APIs. Internally, the identification engine causes the current domain ID of the user to call the identification engine APIs.
  • Only CIs that have the same domain ID as the currently logged-in user's domain display during matching.
  • During matching, if no records are found and a CI needs to be inserted, the CI’s domain ID is the same as the domain ID of the currently logged-in user’s domain.

(https://docs.servicenow.com/bundle/madrid-servicenow-platform/page/product/configuration-management/...

I haven't tried yet, but my next step is to try providing the domain regardless of the instruction above and see what happens.  I can't understand the reliance upon using the logged-in user's domain in this way. 

Matching should be performed on the domain of the CI being imported, not the logged-in user.  The engine can fall back to the logged-in user if no valid domain is provided.  If the logged-in user can't access other domains, then they shouldn't be able to see or edit data in that domain anyway.  This appears to be a significant limitation on the capabilities of this module.

So my question is:

How can I perform a mass import of CI data from our monitoring system, and have CMDB Identification work properly with domain separation?

1 ACCEPTED SOLUTION

So here is what I found - I can impersonate the user that I want on-the-fly using gs.getSession()impersonate(); .  The individual user accounts still need to be created, but once that is done, the script work as expected.

 

Here's a portion of my onBefore script used to do this:

var cmdbUtil = new C_CMDBTransformUtil();
	
	if (grUser.next()) {
		var runUser = gs.getSession().impersonate(grUser.sys_id);
		cmdbUtil.setDataSource('External DataSource Name Here');
		cmdbUtil.identifyAndReconcile_with_Class(source, map, log, targeted_table);
		gs.getSession().impersonate(runUser);
	}
	else {
		gs.log ('No Import User Found');
	}

 

Use a gliderecord to find the user that you want.  In my case, it is a predictable user account for each company.

The nice thing about this is that if a client company isn't configured correctly in our system, the script ignores the record and moves on which avoids creating bad data.

 

C_CMDBTransformUtil(); is a modification to CMDBTransformUtil(); that I found here to allow us to select a CI class as we are importing instead of reclassifying after the fact.

SN did some really weird stuff with this Identification and Reconciliation module that I've had to work around.

View solution in original post

6 REPLIES 6

So here is what I found - I can impersonate the user that I want on-the-fly using gs.getSession()impersonate(); .  The individual user accounts still need to be created, but once that is done, the script work as expected.

 

Here's a portion of my onBefore script used to do this:

var cmdbUtil = new C_CMDBTransformUtil();
	
	if (grUser.next()) {
		var runUser = gs.getSession().impersonate(grUser.sys_id);
		cmdbUtil.setDataSource('External DataSource Name Here');
		cmdbUtil.identifyAndReconcile_with_Class(source, map, log, targeted_table);
		gs.getSession().impersonate(runUser);
	}
	else {
		gs.log ('No Import User Found');
	}

 

Use a gliderecord to find the user that you want.  In my case, it is a predictable user account for each company.

The nice thing about this is that if a client company isn't configured correctly in our system, the script ignores the record and moves on which avoids creating bad data.

 

C_CMDBTransformUtil(); is a modification to CMDBTransformUtil(); that I found here to allow us to select a CI class as we are importing instead of reclassifying after the fact.

SN did some really weird stuff with this Identification and Reconciliation module that I've had to work around.

Ronald Lob
Tera Contributor

In San Diego, ServiceNow provide the option to allow IRE to match CIs accross domains:

How domain separation works in Identification and Reconciliation

Domain separation in the identification engine is enforced when users activate the domain separation plugin. Domain separation for IRE has two modes of operation in domain separated instances:
  • Strict mode (enabled by default): In this mode, identification processes only those CIs in which the domain ID is identical to the domain of the currently logged in user. If duplicate CIs exist across domains (including parent and child domains), then those CIs aren't considered duplicate CIs because their domain IDs don't match.
  • Platform domain separation mode (disabled by default): In this mode, IRE follows the platform domain separation behavior. So during identification, parent domains can access all CIs within their child domains or any of the domains it has visibility into. For more information, see Visibility domains and Contains domains.

    Platform domain separation mode is intended to be used by advanced users for very specific or advanced use cases.

 

https://docs.servicenow.com/bundle/sandiego-servicenow-platform/page/product/configuration-management/concept/domain-separation-identification-reconciliation.html