Add a related list to ALL the CMDB forms for all the different class'

Tim Hannah
Tera Contributor

We have a table that we want to add as a 'related list' on ALL the the different class forms for the CMDB (eg cmdb_ci_alert_group, cmdb_ci_app_server etc) as it relates to all of them.

I have tried adding it to the CMDB with the hope it would push down to all the tables that inherit from there but it still doesn't appear on all.

Can this be scripted?

 

5 REPLIES 5

Marek10
Tera Contributor

Hi Tim,

I have the same problem and have stumbled upon this thread: Adding Related List to cmdb_ci and Child Tables

Unfortunately there is no script in that thread so I used my limited scripting ability to write one:

// sys_ui_related_list - contains tables & views that have ANY related lists
// sys_ui_related_list_entry - contains reference to the sys_ui_related_list (list_id)
// and the string (!) representing the related list (related_list)
// and position (position)

function addRL(tblName, viewName, rLName){
	// !!! tblName, viewName and rlName must exist - not validated in the script !!!
	// searching sys_ui_related_list for name=tblName and view=viewName
	// if does not exist - exits
	// then searches sys_ui_related_list_entry for list_id=sys_id of the sys_ui_related_list found
	// 	and related_list=rLName (how to verify the rLName is proper related list name?)
	// if does not exist finds sys_ui_related_list_entry for list_id=sys_id and highest position
	//  and creates a new sys_ui_related_list_entry with position+1
	// returns null if failed for any reason or sys_id of the sys_ui_related_list_entry added
	var rlSysId;
	
	// step 1 - sys_ui_related_list search
	var grRL = new GlideRecord("sys_ui_related_list");
	grRL.addQuery("name",tblName);
	grRL.addQuery("view",viewName);
	grRL.query();
	if (!grRL.next()){
		gs.warn("ADDRL: "+tblName+" / "+viewName+" : No sys_ui_related_list : Exiting!");
		return null;
	}
	// else
	rlSysId = grRL.getValue("sys_id");
	gs.debug("ADDRL: "+tblName+" / "+viewName+" : Found sys_ui_related_list : sys_id="+rlSysId);
	
	// step 2 - sys_ui_related_list_entry search
	var grRLE = new GlideRecord("sys_ui_related_list_entry");
	grRLE.addQuery("list_id",rlSysId);
	grRLE.addQuery("related_list",rLName);
	grRLE.query();
	if (grRLE.next()){
		gs.warn("ADDRL: "+tblName+" / "+viewName+" : Found existing related list "+rLName+" : Exiting!");
		return null;
	}
	// else
	// step 3 - new sys_ui_related_list_entry - last position+1
	var grRLEn = new GlideRecord("sys_ui_related_list_entry");
	grRLEn.addQuery("list_id",rlSysId);
	grRLEn.orderByDesc("position");
	grRLEn.setLimit(1);
	grRLEn.query();
	if (grRLEn.next()){
		gs.debug("ADDRL: "+tblName+" / "+viewName+" : Last related list "+grRLEn.getValue("related_list")+" on pos "+grRLEn.getValue("position"));
		var lastRL = grRLEn.getValue("position");
		lastRL++;
		grRLEn.newRecord();
		grRLEn.setValue("list_id",rlSysId);
		grRLEn.setValue("related_list",rLName);
		grRLEn.setValue("position",lastRL);
		grRLEn.insert();
		grRLEn.query();
		if (grRLEn.next()){
			gs.info("ADDRL: "+tblName+" / "+viewName+" : related list "+grRLEn.getValue("related_list")+" : added on pos "+grRLEn.getValue("position"));
		}
	}
	
	return 1;
}


addRL("cmdb_ci_computer","Default view","sn_cmp_rsrc_tag_history.cmdb_ci");
addRL("cmdb_ci_apic_host","Default view","sn_cmp_rsrc_tag_history.cmdb_ci");

You can run the function for tables you like (two examples above) but it will not create a new related list record (sys_ui_related_list) if one does not exist already. I observed many CMDB tables do not have these ootb until you open a form - it is dynamically created then. I do not know how the system determines which RLs should be added for the start - I suppose the parent table is used as a template.

If you noticed any possible improvements to the script above I would be grateful - I am a beginner in SN scripting.

Best regards,

Marek

This is great! It benefited me today to some extent.

Hi Marek, I have the same issue. I am new to this and wondered, where would you run this script? Do you create a scheduled job and run it from there?

Thanks.

Igor

Hi Igor,

I use "background script" to run one-time code like this.

Best regards,

Marek