Using another object's directives in a host or service check

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.

Getting ready

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.

How to do it…

We can create a reference to the values of another host's directives like so:

  1. Change to the objects' configuration directory for Nagios Core. The default is /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
    
  2. Edit the file containing the definition for the service that contains the attribute you want dynamically expanded—that is, the 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
    }
  3. Replace the data you want dynamically expanded with a macro in the following format:
    $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$
    }
  4. Validate the configuration and restart the Nagios Core server, as follows:
    # /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.

How it works…

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.

There's more…

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.

See also

  • Customizing an existing command, Chapter 2, Working with Commands and Plugins
  • The Using custom directives recipe in this chapter
  • The Using inheritance to simplify configuration recipe in this chapter
  • The Dynamically building host definitions recipe in this chapter
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.119.235.79