Syncmapping block
The mappings performed during CMDB-synchronization are specified in syncmapping blocks in TPL. A syncmapping is similar to a pattern, but it triggers from a queued synchronization action, rather than from data being updated in the data store.
The form of a syncmapping is:
syncmapping name version
description
overview
overview_entries
end overview;
[constants
constant_definitions
end constants;]
mapping mapping_source as source_name
mapping_definitions
end mapping;
body
body_details
end body;
end syncmapping;
As with pattern blocks, the name, version, and description are mandatory.
Pattern-templates are provided to help you create your own syncmappings.
Overview section
The overview is required. It contains information about the pattern and the entities it creates. It must contain a tags entry, and can have an optional datamodel entry, as described in Data models.
The overview section can also have an optional overrides entry, which enables you to change the behavior of an existing mapping and to preserve those changes on subsequent TKU updates to the overridden mapping. Non-syncmapping patterns have an "overridden" flag displayed on the pattern management page, syncmappings do not.
Here is an excerpt from an overriding mapping:
*from* CMDB.Host_ComputerSystem *import* Host_ComputerSystem 1.2;
*from* CMDB.SoftwareInstance_SoftwareServer *import* SoftwareInstance_SoftwareServer 3.2;
// The mapping referred to by the overrides keyword must be imported
*syncmapping* SoftwareInstance_SoftwareServer_override 3.2
"""
Example override mapping.
"""
*overview*
*tags* CMDB, Core_Mapping;
*datamodel* 0, 1, 2, 3, 4, 5, 6;
*overrides* SoftwareInstance_SoftwareServer; // The overridden pattern is imported above
*end* *overview*;
*mapping* *from* Host_ComputerSystem.host *as* host
*traverse* Host:HostedSoftware::SoftwareInstance *as* si_node
*traverse* Element:Maintainer:Pattern:Pattern *as* si_pattern
*end* *traverse*;
...
Mapping section
The mapping section declares the starting point for the mapping, the structure of source data retrieved from the Discovery model, and the target CIs created in the CMDB model. It does not describe how the source data is transformed to the target model — that is performed in the body section.
Mapping source
Each mapping is either a root mapping, meaning that it is invoked by the synchronization of a single root node with the corresponding kind, or an extension mapping, meaning that it extends another mapping at a suitable point.
You should not use DDD directly in mappings, rather, you should copy the required DDD into the inferred model first.
Root mappings have a mapping declaration using the on keyword:
_mapping content..._
*end* *mapping*
For example, this specifies the root mapping for Host nodes:
Extension mappings have a mapping declaration using the from keyword:
For example:
The source_scoped_name is the name of a source mapping variable from another mapping block, either the source name specified in the mapping declaration, or a traversal name as described below.
Multiple "From" expressions in the mappings block
Multiple parent mappings are supported, by using more than one "From" expression in the mapping block, for example:
...
mapping from Host_ComputerSystem.host from Cluster.cluster as hosting_system
...
In this example the mapping input can be from a Host or a Cluster node in the (BMC Discovery model). All of the input parameters used in the mapping statement must have corresponding references in the body. An example in the case of the above mapping statement is:
The hosting system (in the CMDB model) is either a BMC_Cluster or a BMC_ComputerSystem. The order matters here; the interpreter takes the first defined object which it finds (checking from left to right).
Mapping traversals
The source subgraph is declared using traverse clauses inside the mapping with a syntax similar to traversals in search expressions:
_traversal contents..._
*end* *traverse*
The nodename defined by the traversal can only be used in a
You can also define a relationship relname for a traverse clause inside the mapping. The first is the name of the relationship and the second is the name of the node.
_traversal contents..._
*end* *traverse*
In each case the relname and nodename defined by the traversal can only be used in a
Where clauses
The initial source node and the results of traversals can be filtered with where clauses, specified before the as token. where clauses in mapping blocks use the same subset of search where clauses as trigger conditions in pattern blocks.
*mapping* *from* _source_scoped_name_ *where* _condition_ *as* _name_
*traverse* _traversal_specification_ *where* _condition_ *as* _name_
However, you cannot use search in a syncmapping. CMDB synchronization takes a graph of connected nodes in BMC Helix Discovery and transforms them into a graph of connected CIs in the CMDB. If the where clause contains a search there is no guarantee of any such connection.
Target CI declarations
As the subgraph is processed in the body, target CIs are specified. The mapping block contains declarations of the CIs that are mapped, in the form:
For example:
Targets are specified within the traversal structure. For example, part of the mapping of virtual machines is as follows:
*traverse* ContainedHost:HostContainment:HostContainer:SoftwareInstance *as* vm_si
vse *->* BMC_VirtualSystemEnabler;
*traverse* RunningSoftware:HostedSoftware:Host:Host *as* containing_host
containing_cs *->* BMC_ComputerSystem;
*end* *traverse*;
*end* *traverse*;
*end* *mapping*;
Grouping
In some circumstances, a number of nodes in the Discovery model must be grouped together to construct a single CI in the CMDB model. This is declared in the mapping with a group block. The form of a group block is
*group* _group_name_
_group contents..._
*expand* *group* *as* _expansion_name_
_expansion contents..._
*end* *expand*;
*end* *group*;
*end* *traverse*;
The declaration indicates that nodes from the containing traversal will be grouped together (according to rules specified in a group block in the body), and then the group will be expanded to the individual group members. The expand is not required if there is no need to process the individual nodes within the group.
Syncmapping body
The body of a syncmapping is responsible for implementing the mapping described in the mapping block. The majority of language features and functions available in pattern body blocks are permitted, except that functions in the following namespaces are not available since they are only appropriate for patterns that perform discovery and construct the Discovery model.
- discovery
- inference
- model
Additionally, user-defined functions are not supported.
Body execution
The body of a syncmapping is executed at a time that depends upon the mapping source definition.
The body of a root mapping (specified with mapping on) is executed at the time the root node is scheduled for synchronization.
The body of an extension mapping (specified with mapping from) that extends the source node of another mapping is executed when the body of the extended mapping completes.
The body of an extension mapping that extends a traversed-to node of another mapping is executed each time the associated for each loop (see below) completes.
When a node in the Discovery data store is marked as destroyed, only the root mapping's body is executed, and the target root CI is scheduled for deletion in the CMDB. When the delete is synchronized with the CMDB, the root CI and all the related CIs previously created by the mapping are deleted. For best performance during deletion, root mappings should not perform any traversals or other time-consuming activities.
CI definition
CIs and relationships in the CMDB are specified with functions in the sync namespace similar to those in the model namespace used within pattern blocks.
Any CMDB class can be specified with a function call of the form
Any class name can be specified. Specifying a class that is not defined in the CMDB results in a run-time error. The key attribute must be set, and is used to populate the ADDMIntegrationId attribute in the CMDB. Any other attribute name can be set; attributes that are not defined in the CI class are ignored.
The result of the function must be assigned to a target CI name specified in the mapping block. The class specified in the function must be the same as the one specified in the mapping or a subclass of it.
CI class namespaces
CMDB classes are assumed to be in the BMC.CORE namespace. To refer to a class in a different namespace, provide a namespace parameter to the function call:
The namespace must be a literal string — it cannot be constructed at runtime.
Shared CIs
The subgraph of data in the Discovery model is transformed into a subgraph of CIs in the target CMDB model. Most of the CIs belong to a single target subgraph, but some are shared by more than one subgraph. An example is the BMC_IPConnectivitySubnet CI that is shared by all the computers on a particular subnet. For deletion to work correctly, the system must know that such CIs are shared. This is achieved by calling the function in the sync.shared namespace:
External CIs
Similarly, it is sometimes necessary to specify a relationship to a CI that is not part of the target subgraph. An example is to relate the BMC_ComputerSystem for a physical host to the one for a virtual host — the two CIs belong to different subgraphs. External CIs are specified with a function in the sync.external namespace:
The key must be specified, and namespace must be specified if required. No other attributes can be set.
It is not an error if a CI with the specified key does not exist in the CMDB. In that situation, the CI and any relationships to it are simply ignored.
Cross-reference CIs
As the mapping is processed, the CIs are specified in a tree traversal across the graph. To refer to a CI specified in a different branch of the tree, it can be specified with a function in the sync.crossref namespace:
The key must be specified, and namespace must be specified if required. No other attributes can be set.
It is a runtime error to specify a cross-reference to a CI that is not fully specified elsewhere within the mapping.
TokenId rules
TokenId is an attribute that, in some circumstances, aids the reconciliation of CIs populated by multiple data sources. BMC Helix Discovery sets TokenId depending on the Node kind.
For most Nodes, TokenId is one of the forms:
or
or
For databases, TokenId is a database host found as a result of all possible combinations of where the database might be running:
and
For the Fibre Channel Node, TokenId is of the form:
For physical hosts, TokenId is of the form:
If the domain name is unavailable, then
For virtual hosts that are running in the cloud, TokenId contains instance_id.
- For Alibaba, TokenId is of the form:
- For Azure, TokenId is of the form:
- For AWS, TokenId is of the form:
- For GCP, TokenId is of the form:
- For IBM, TokenId is of the form:
- For OCI, TokenId is of the form:
For virtual hosts that are running in the hypervisor, TokenId contains UUID.
- For AHV, TokenId is of the form:
- For Hyper-V, the UUID is only available on the physical machine, so TokenId is only set for virtual machines that have been successfully linked to their hosting physical machines:
- For KVM (including RedHat Enterprise Virtualization), TokenId is of the form:
- For VMware, TokenId is of the form where each letter represents a hexadecimal digit:
- For Xen (including Oracle VM), TokenId is of the form:
The following table shows how TokenId looks like for different Node Kinds:
Node Kind | CI | TokenId |
---|---|---|
AdminCollection | BMC_AdminDomain | key |
Cluster (cloud) | BMC_Cluster | key |
LoadBalancerService | BMC_LogicalSystemComponent | ADDM:%key% |
LoadBalancerPool | BMC_ResourcePool | ADDM:%key% |
CloudManagementGroup | BMC_AdminDomain | cloud_id |
CloudProvider | BMC_CloudInstance | key |
CloudRegion | BMC_CloudInstance | key |
CloudService | BMC_CloudInstance | key |
Cluster | BMC_Cluster | ADDM:%hashed_key% |
Database (cloud) | BMC_DataBase | ADDM:%key% |
Database | BMC_DataBase | %hosting_ci.TokenId%:%database_node.type%:%si_instance%:%database_node.instance% |
%hosting_ci.Name%:%database_node.type%:%si_instance%:%database_node.instance% | ||
HardwareComponent | BMC_HardwareSystemComponent | ADDM:%hashed_key% |
HardwareContainer | BMC_ComputerSystem | ADDM:%hashed_key% |
HostContainer | BMC_ComputerSystem | ADDM:%hashed_key% |
Host | BMC_ComputerSystem | %host.hostname%:%host.dns_domain% |
%host.hostname% | ||
ALIBABA-ID:%alibaba_instance_id% | ||
AWS-ID:%aws_instance_id% | ||
GCP-ID:%gce_instance_id% | ||
IBM-ID:%instance_id% | ||
OCI-ID:%ocid% | ||
AZURE-ID:%azure_vm_id% | ||
HYPERV-ID:%vm_uuid% | ||
XEN-ID:%uuid% | ||
KVM-UUID:%uuid% | ||
AHV-UUID:%uuid% | ||
VI-UUID:%uuid% | ||
LoadBalancerGroup | BMC_Cluster | ADDM:%key% |
MFPart | BMC_ComputerSystem | key |
Namespace | BMC_AdminDomain | key |
Deployment | BMC_ConcreteCollection | key |
NetworkService | BMC_LogicalSystemComponent | ADDM:%key% |
FibreChannelPort | BMC_NetworkPort | WWN:%wwpn% |
SoftwareCluster | BMC_Cluster | ADDM:%hashed_key% |
SoftwareComponent | BMC_ApplicationService | ADDM:%hashed_key% |
SoftwareInstance | BMC_ApplicationSystem | ADDM:%hashed_key% |
SoftwareInstance | BMC_SoftwareServer | ADDM:%hashed_key% |
VirtualMachine | BMC_VirtualSystemEnabler | ADDM:%hashed_key% |
StorageDevice | BMC_Cluster | ADDM:%key% |
StoragePool | BMC_ResourcePool | ADDM:%key% |
StorageSystemGroup | BMC_Cluster | ADDM:%key% |
StorageProcessor | BMC_HardwarePackage | ADDM:%key% |
HardwareContainer | BMC_HardwareSystemComponent | ADDM:%hashed_key% |
Relationship definition
Relationships are specified with functions in the sync.rel namespace:
Destination := _dest_val_,
Name := "_RELNAME_" _[, ... ]_);
The first two parameters must be Source and Destination. Any other attributes can also be set; Name is not required, but it is conventionally always set.
The Impacted and ImpactWeight attributes can be used to create impact relationships. They specify impact direction and percentage respectively. For example, an ImpactWeight of 25 might be appropriate when representing an impact relationship between a BMC_ComputerSystem and BMC_Cluster, where there are four computers in a cluster. The value assigned to Impacted must be the Source or Destination CI appearing in the same definition.
Source := computersystem,
Destination := cluster_ci,
Name := "CLUSTEREDSYSTEM",
Impacted := cluster_ci,
ImpactWeight := cluster_rel.impact_weight
);
Note that prior to tpl 1.10 multiple relationship definitions were needed to represent a single impact relationship in the CMDB. This was because the way in which impact is represented in the CMDB depends on the data model in effect (see below). In tpl 1.10 and later, only one definition is required.
Traversal looping
One of the main activities performed in the body is to iterate over the nodes reached through the traversals specified in the mapping block. A for each loop is used to iterate over the named nodes:
...
*end* *for*
The nesting structure of for each loops in the body must match the nesting structure of the traverse expressions in the mapping block.
A for each loop is required even if the corresponding traversal is expected to reach just one node. There is no other way to access the state of the traversed-to node.
Group block
When the mapping block specifies a group, there must be a corresponding group block in the body. The group block will always be inside a for each block, either directly within a single syncmapping body or in an extended source syncmapping.
A group block takes the form:
...
ident := _group_identifier_;
*group* _group_name_ *with* ident *do*
...
*for* *each* _expand_name_ *do*
...
*end* *for*;
*end* *group*;
*end* *for*;
The grouping is evaluated in two phases. In the first phase, every iteration of the surrounding for each loop is executed. The nodes are grouped according to the identifier provided to the group expression. After all the iterations of the for each loop, the group block is executed once for each group. If the group declaration in the mapping block contains an expand declaration, there should be a corresponding for each loop in the body.
The group content is executed in a context based on an arbitrary member of the group. Any local variables from the surrounding loop will therefore be valid for a member of the group, but there is no guarantee that it will be the same group member each time a particular group is processed.
Data models
Different versions of the CMDB have subtly different data models. Syncmappings can support multiple data models with datamodel declarations. CMDB data models are assigned simple integer values:
Data model | CMDB versions | Effect |
---|---|---|
6 | 7.6.03 and later | HasImpact and ImpactDirection attributes are set as appropriate. |
5 | 7.6.03 and later | Only to be used with legacy SIM version 7.4. BMC_Impact relationships with Name “ImpactOnly” are created. |
4 | 7.6.03 and later | No impact details are set by BMC Discovery. They may be set by Impact Normalization in the CMDB. |
3 | 7.6 before 7.6.03 | BMC_Impact relationships with name “IMPACT” are created. |
2 | 7.5 | BMC_Impact relationships with name “IMPACT” are created. |
A syncmapping can limit itself to a particular set of data models with a datamodel declaration in the overview:
*tags* Some_tags;
*datamodel* 3, 4; // Only CMDB 7.6.x
*end* *overview*
The body of a syncmapping can further modify its behavior for different data models with a datamodel block. The datamodel block only executes if the data model in effect matches the declaration:
*datamodel* 2, 3 *do*
sync.rel.BMC_Dependency(
Source := ci,
Destination := other_ci,
Name := "DEPENDENCY_NAME"
);
*end* *datamodel*;
The data model in effect is not chosen automatically. After you configure CMDB synchronization, the data model is selected. This is described in Setting-up-a-CMDB-synchronization-connection.