In some cases where checks of hosts or services depend on each other, we may need to use information in a definition for check_command
that's dependent on a property of another host or service. In these cases, you may end up with an unnecessary duplication of this information, so if it changes in one place, the check may break if it's not changed in another. These situations can be hard to remember and can cause confusing errors when forgotten; so, ideally, we would want our configuration to be more dynamic so that we only have to change such pieces of information in one place.
For example, to check whether two BGP routing peers are correctly established and that they exchange routes via SNMP, we would need the value of address
of the other one so that for each of them, we know which peer to check. Suppose we have these two hosts configured based on a bgp-router
template; in this case, we would execute the following code:
define host { use bgp-router host_name bgp-router-01.example.net alias bgp-router-01 address 192.0.2.96 } define host { use bgp-router host_name bgp-router-02.example.net alias bgp-router-02 address 192.0.2.97 }
If we wanted to apply a check_bgp_peer
command to each of them to verify that the BGP data retrieved from SNMP for both of them is valid, we would need to refer to the address of the other host in check_command
; it may look something similar to this:
define service { use snmp-service host_name bgp-router-01.example.net service_description BGP_PEER_ROUTER_02 check_command check_bgp_peer!192.0.2.97 } define service { use snmp-service host_name bgp-router-02.example.net service_description BGP_PEER_ROUTER_01 check_command check_bgp_peer!192.0.2.96 }
This would work, but it means that if the IP address of either of the peers were to change, we'd need to change it in two places; in the address
of the host object and the check_command
of its peer's service check. In this recipe, we'll arrange for the configuration to refer to the address of the other host rather than repeating it in the configuration using a special syntax of macros. These are known in Nagios as on-demand macros.
You will need to have a server running Nagios Core 4.0 or later, access to the command line to change its configuration, and a basic understanding of how directives apply to hosts and services and how hosts and services refer to one another. These are discussed in chapters 1 and 2.
You will also need at least two hosts configured that are in a situation where it's necessary for at least one of their services to refer to the configured values of the other host, as with our example.
We can create a reference to the values of another host's directives like so:
/usr/local/nagios/etc/objects
. If you've put the definition for your hosts and services in a different file, move to its directory instead via the following line of code:# cd /usr/local/nagios/etc/objects
check_command
that uses the value of the directive of another host. In this case, we want to edit the check_command
of our BGP_PEER_ROUTER_01
and BGP_ROUTER_01
services and replace the hardcoded IP address of the peer in the lines highlighted here:define service { use snmp-service host_name bgp-router-01.example.net service_description BGP_PEER_ROUTER_02 check_command check_bgp_peer!192.0.2.97 } define service { use snmp-service host_name bgp-router-02.example.net service_description BGP_PEER_ROUTER_01 check_command check_bgp_peer!192.0.2.96 }
$HOST<macro>:<hostname>$
In this case, we want the $HOSTADDRESS$
macro of the bgp-router-02
host in the first service and the same property for the bgp-router-01
host in the second, so our new configuration will look similar to this:
define service { use snmp-service host_name bgp-router-01.example.net service_description BGP_PEER_ROUTER_02 check_command check_bgp_peer!$HOSTADDRESS:bgp-router02.example.net$ } define service { use snmp-service host_name bgp-router-02.example.net service_description BGP_PEER_ROUTER_01 check_command check_bgp_peer!$HOSTADDRESS:bgp-router01.example.net$ }
# /usr/local/nagios/bin/nagios -v /usr/local/nagios/etc/nagios.cfg
With this done, the checks we have already established should continue working as normal but with less duplication and a little more clarity in the configuration.
When the on-demand $HOSTADDRESS:bgp-router-02.example.net$
and $HOSTADDRESS:bgp-router-01.example.net$
macros are expanded for the execution of the check_command
, Nagios Core refers to the address
directive for a host, just as it normally would with a $HOSTADDRESS$
macro without the hostname specified. The difference is that with the colon added and the name of another host given, Nagios Core will refer to the value of the macro for this host and not the host for which the service is defined.
In our example, $HOSTADDRESS:bgp-router-02.example.net$
would expand to 192.0.2.97
, the value of the address
directive for bgp-router-02.example.net
, and $HOSTADDRESS:bgp-router-01.example.net$
to 192.0.2.96
, the value of the address directive for bgp-router-01.example.net
. The checks would therefore end up running with the same arguments as they had when they were hardcoded, but the information will not be duplicated in the configuration. It also becomes easier to understand what is checked when the configuration is read by someone else as the hostname for the address is explicitly given.
The $HOSTADDRESS$
macro is not the only one that can be expanded in this way. The $HOSTNAME$
and $HOSTALIAS$
macros and even dynamic information such as $HOSTSTATE$
can be expanded as an on-demand macro for another host.
Similarly, hosts are not the only object for which this works. You can expand macros for contacts, hostgroups, and servicegroups in the same way. For example, $CONTACTADDRESS1:admin$
, $HOSTGROUPALIAS:webservers$
, and $SERVICEGROUPNOTES:snmp-checks$
would all work if given objects of the appropriate type with these names.
You can refer to service objects with a similar syntax, allowing you to specify both the host name and the service description for the service that has the values you want to reference by adding another colon and service_description
for the service; for example, $SERVICESTATE:webserver-01:HTTP$
would work for a service check called HTTPS
on a host named webserver-01
.
The Nagios Core documentation goes into more depth about the possibilities for on-demand macros at https://assets.nagios.com/downloads/nagioscore/docs/nagioscore/4/en/macros.html.
18.119.235.79