Skip to main content

Howtos

Recursive Structures with Render Type Inline

Extreme Cornercase

This type of constellation will only occur in very specific use cases. But most complex IT landscapes will encounter at least one such use case. Most of these use cases are handled by the provided default configurations.

If the default configurations do not match your requirements, we're more than happy to help you find the correct solution. Please contact us on arc46 support.

If you want(!) to attempt this on your own, it only looks complicated. Once you've understood the concept it is very straight forward.

info

Recursive structures are only problematic when rendered inline! Any other Render Type cannot cause endless recursion.

Some ServiceNow entities have recursive parent-child relations, e.g. cmn_location and cmdb_ci_ip_pool. This can lead to endless loops when rendering these entities as Inline Content.

Example

When requesting IP Pool 172.22.0.0/16 (dark blue in the middle) we want to render its parent IP pool as well as its subnets, but would - without further configuration - end up resolving and rendering the red components, as these are subnets of the parent IP pool too. This results in an endless recursion. Your request would be aborted (best case) and/or impact your ServiceNow instance (worst case).

Parent-Child Relations for IP Pools

Parent-Child Relations for IP Pools

Parent or 'up' relations

inline vs recursive configurations

The naming convention for the provided default configurations defines inline and recursive configuration variants in all cases where a recursive 'parent' or 'up' relationship exists.

inline will only render the immediate 'parent', whereas recursive will render all 'parents' recursively. 'parent' is a placeholder name for any reference pointing to the same ServiceNow class/table as the referencing class/table.

In our cmdb_ci_ip_pool example we have

  • cmdb_ci_ip_pool_inline (only immediate parent)
  • cmdb_ci_ip_pool_recursive (all parents)

that render IP pool 10.7.0.0/16 as

JSON
{
"metadata": {
"Caveat": "THIS IS BETA CODE AND SUBJECT TO CHANGE AT ANY TIME!",
"powered_by": "arc46.io",
"git": "DataRestApi-0.1.1+4-5218ee6-dirty",
"build": "2024-05-10T04:53:44.795Z",
"licensed_max_entities": "Unlimited",
"config": "cmdb_ci_ip_pool_inline",
"limit_configs": 10,
"request_received": "2024-05-13T11:09:17.444Z",
"parse_config": "34ms",
"query_start": "2024-05-13T11:09:17.478Z",
"query_duration": "1ms",
"query_returned": "2024-05-13T11:09:17.479Z",
"row_count": 1,
"provided_filter": "base_cidr=172.22.120.0/23",
"combined_filter": "base_cidr=172.22.120.0/23"
},
"data": [
{
"cidr": "172.22.120.0/23",
"last_discovered": "2024-05-13T10:17:08Z",
"name": "172.22.120.0/23",
"parent_pool": {
"cidr": "172.22.0.0/16",
"last_discovered": "2024-05-12T22:41:09Z",
"name": "172.22.0.0/16",
"sys_class_name": "cmdb_ci_ip_pool",
"sys_id": "007822ad87fdc6903efcec230cbb350b"
},
"sys_class_name": "cmdb_ci_ip_network_subnet",
"sys_id": "07435fe587f10a903efcec230cbb3558"
}
],
"relations": {},
"referenced": {}
}

How do we do it?

This is where things get slightly ... complicated. (And again: you can, but do not have to, do this on your own. And if you need help, we're just one click away.)

cmdb_ci_ip_pool_inline:

  1. cmdb_ci_ip_pool_inline defines Reference Group Names as inline.
  2. Reference Group Name inline for property parent_pool defines a target config cmdb_ci_ip_pool_inline_stop.
    The rendered content of the configuration cmdb_ci_ip_pool_inline_stop is identical to that of cmdb_ci_ip_pool_inline. We use the different configuration name to enable different reference configurations for parent_pool.
  3. Resolving references for cmdb_ci_ip_pool_inline_stop will return a Disable Render Type for parent_pool ending the recursion.

cmdb_ci_ip_pool_recursive:

  1. cmdb_ci_ip_pool_recursive defines Reference Group Names as recursive.
  2. Reference Group Name recursive for property parent_pool defines target config cmdb_ci_ip_pool_inline_up. The rendered content of the configuration cmdb_ci_ip_pool_inline_up is identical to that of
  3. Configuration cmdb_ci_ip_pool_inline_up is mostly identical to cmdb_ci_ip_pool_inline.
  4. Resolving references for cmdb_ci_ip_pool_inline_up will return a Render Type inline_content with target config cmdb_ci_ip_pool_up for parent_pool.
  5. We're back at 3.

Parent Relations for IP Pools

Parent Relations for IP Pools

Children or 'down' relations

When rendering recursive child relations, we have the following challenges:

  • Child entities should not render their parents.
  • We have to be able to stop the recursion after the first child level.

We achieve this by defining an extra configuration variant, *_down.

By convention *_down configuration variants disable the rendering of the 'parent' reference by setting a Render Type of the parent reference to disabled.

*_down configuration variants further allow us to explicitly request the rendering of recursive relations - or not, depending on what we want to retrieve.

JSON

(471 IP Pools retrieved.)

{
"metadata": {
"Caveat": "THIS IS BETA CODE AND SUBJECT TO CHANGE AT ANY TIME!",
"powered_by": "arc46.io",
"git": "DataRestApi-0.1.1+4-5218ee6-dirty",
"build": "2024-05-10T04:53:44.795Z",
"licensed_max_entities": "Unlimited",
"config": "cmdb_ci_ip_pool_inline",
"limit_configs": 10,
"requested_relations": {
"cmdb_ci_ip_pool_inline": [
"ip_pool_children_inline"
]
},
"request_received": "2024-05-13T11:52:20.092Z",
"parse_config": "65ms",
"query_start": "2024-05-13T11:52:20.157Z",
"query_duration": "3ms",
"query_returned": "2024-05-13T11:52:20.160Z",
"row_count": 1,
"provided_filter": "base_cidr=172.0.0.0/8",
"combined_filter": "base_cidr=172.0.0.0/8"
},
"data": [
{
"cidr": "172.0.0.0/8",
"last_discovered": "2024-05-12T22:41:08Z",
"name": "172.0.0.0/8",
"sys_class_name": "cmdb_ci_ip_pool",
"sys_id": "6f58a225873906146dc863540cbb3512",
"subnets": [
{
"cidr": "172.22.0.0/16",
"last_discovered": "2024-05-12T22:41:09Z",
"name": "172.22.0.0/16",
"sys_class_name": "cmdb_ci_ip_pool",
"sys_id": "007822ad87fdc6903efcec230cbb350b"
},
...
(1000
subnets)
{
"cidr": "172.28.90.0/24",
"last_discovered": "2024-05-13T10:18:46Z",
"name": "172.28.90.0/24",
"sys_class_name": "cmdb_ci_ip_network_subnet",
"sys_id": "fd359329873d06146dc863540cbb35ae"
}
]
}
],
"relations": {},
"referenced": {}
}

How do we do it?

This is slightly less complicated than the brain-teaser inline vs recursive documented above, but it still might be a challenge. (And again: you can, but do not have to do this on your own. And if you need help, we're just one click away.)

cmdb_ci_ip_pool_inline: (This is the same for cmdb_ci_ip_pool_recursive)

  1. We start with a request http://your-instance/api/x_a46gh_squidx/v1/data/cmdb_ci_ip_pool_inline.
  2. We want to render all children of our root entities, so we add relations=ip_pool_children_inline. This has the effect of rendering the 'Backreferences' ip_pool_children_inline with a target config cmdb_ci_ip_pool_down.
  3. Resolving references for cmdb_ci_ip_pool_inline_down will return a Render Type disabled for parent_pool, preventing the rendering of the parent in the child.
  4. As the target config for the children is cmdb_ci_ip_pool_inline_down as opposed to cmdb_ci_ip_pool_inline the relation request only applies to the root element.
    • If you only want the first level of children, you're done. Your final request is http://your-instance/api/x_a46gh_squidx/v1/data/cmdb_ci_ip_pool_inline?relations=ip_pool_children_inline.
    • If you also want to render the children of the children, continue with 5.
  5. The first level 'children' are rendered with a target config cmdb_ci_ip_pool_inline_down. In order to get their children we have to explicitly request the corresponding relation, so we add cmdb_ci_ip_pool_inline_down.relations=ip_pool_children_inline. This will resolve the relation ip_pool_children_inline for all cmdb_ci_ip_pool_inline_down. As no further change in target config happens, this results in a recursive structure. Your final request is http://your-instance/api/x_a46gh_squidx/v1/data/cmdb_ci_ip_pool_inline?relations=ip_pool_children_inline&cmdb_ci_ip_pool_inline_down.relations=ip_pool_children_inline.

Child Relations for IP Pools

Child Relations for IP Pools

We track. Ok?