- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
‎08-30-2024 12:14 PM
Hello, I wanted to set up an automatic calculation for how many rack units are occupying a rack. I've created a field entry for the devices with the expectation that they will have a value for how many rack units they will occupy (such as servers and any other devices that could be installed within a rack such as switches, routers, PSUs, etc). And then the plan would be for using the CI Relationship "contains::contained by" to pull the items within the rack and then sum up the rack units and display for the "Rack units in use" field on a given Rack. Currently I have the field on the Servers table (cmdb_ci_servers) and planning on adding the field to more later as we identify what items will be tracked in the Racks. I presume I will be using the Script type rather than Formula.
Solved! Go to Solution.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
‎09-06-2024 10:26 PM
Instead of creating a new GlideRecord, you can directly access the child CI like this:
// Initialize the sum
var totalRackUnits = 0;
// Get the list of CIs contained by the rack
var grContainment = new GlideRecord('cmdb_rel_ci');
grContainment.addQuery('parent', current.sys_id); // Assuming current is the Rack CI
grContainment.addQuery('type.name', 'contains::contained by');
grContainment.query();
while (grContainment.next()) {
if (grContainment.child) { // Directly check if the child CI exists
totalRackUnits += parseInt(grContainment.child.u_rack_units || 0); // Access the rack units field from child CI
}
}
// Update the rack's "Rack units in use" field
current.u_rack_units_in_use = totalRackUnits;
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
‎08-31-2024 03:04 AM - edited ‎08-31-2024 03:09 AM
Understanding the Problem:
You're trying to automatically calculate the total rack units occupied by devices within a rack. You have a field on the cmdb_ci_servers table to capture the rack units occupied by servers. You plan to extend this to other device types and use CI Relationships to sum the values.
Proposed Solution:
Create a Custom Calculated Field:
- On the cmdb_ci_rack table, create a calculated field named rack_units_in_use.
- Set the data type to integer.
- Select "Script" as the calculation type.
Write the Script:
// Initialize the sum
var totalRackUnits = 0;
// Get the list of CIs contained by the rack
var grContainment = new GlideRecord('cmdb_rel_ci');
grContainment.addQuery('parent', current.sys_id); // Assuming current is the Rack CI
grContainment.addQuery('type.name', 'contains::contained by');
grContainment.query();
while (grContainment.next()) {
var childCI = new GlideRecord(grContainment.child.cmdb_ci);
if (childCI.get(grContainment.child.sys_id)) {
totalRackUnits += parseInt(childCI.u_rack_units || 0); // Assuming u_rack_units is the field name
}
}
// Update the rack's "Rack units in use" field
current.u_rack_units_in_use = totalRackUnits;
Explanation:
- The script queries the cmdb_ci_rack_device table for devices contained within the current rack.
- It iterates through each device, retrieves the corresponding cmdb_ci_server record, and adds the rack_units value to the total.
- Finally, it sets the calculated field rack_units_in_use on the current rack record.
Additional Considerations:
- Device Types: Ensure that the script handles other device types besides servers by adjusting the device.get(gr.device) line.
- Performance: For large numbers of devices, consider optimizing the query and calculations to improve performance.
- Data Integrity: Implement validation rules to ensure that rack_units values are valid integers.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
‎09-03-2024 01:00 PM - edited ‎09-06-2024 05:57 AM
I think this is the solution, however I'm having trouble getting a result from it. Is the following line supposed to be a new gliderecord for cmdb_ci?
var childCI = new GlideRecord(grContainment.child.cmdb_ci);
Any test records I have that contains a server that has a u_rack_unit value, it returns with a null value, not even an Int. It might even give a null value for servers that DON'T have a u_rack_unit value, haven't had an opportunity to test that yet...But it seems like it is getting stuck in the while loop, and doesn't exit, therefore it never returns a proper value.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
‎09-06-2024 06:04 AM
I have determined that the error occurs somewhere within this if statement:
if (childCI.get(grContainment.child.sys_id))
It never reaches within the if statement.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
‎09-06-2024 11:05 AM