Using m4 with Nagios: Advanced Ideas

Nagios configuration has been traditionally cumbersome and extensive; there are a lot of things to configure. The addition of templating some time ago helped, but not entirely. A configuration element such as a server or a switch can take up a huge amount of configuration and be quite repetitive, too.

Using m4 can alleviate all of these problems. When combined with GNU Make and Nagios configuration directories, changing the configuration can be done quite simply and easily.

With this beginning of a Makefile in /etc/nagios, all *.cfg files will be converted to *.m4 files as they are included as
prerequisites:

M4=/usr/bin/m4
 
%.cfg : %.m4
        $(M4) -I conf.d/includes < $< > $*.cfg

With this default rule in place, and all configuration files in the conf.d directory can be converted with this
Makefile syntax:

FILES=$(wildcard conf.d/*.cfg)
 
all: $(FILES)

This uses the GNU Make wildcard function to generate a list of files easily. Other directories
can be added with new calls to the wildcard function; it is not recursive and won’t descend
into directories.

Finish off the Makefile with these:


restart: all
        service nagios3 restart
 
.PHONY: all restart

This makes it possible to put the m4 files into conf.d (with matching cfg file or it won’t activate!) and use
a library of predefined macro files included in conf.d/includes. If make is called with make restart then all
configuration files will be processed by m4 as needed and Nagios will be reloaded.

M4 should be included in the base Linux install – but often isn’t. Load it and use it today!

5 Programs That Should be in the Base Install

There are a number of programs that never seem to be installed with the base system, but should be. In this day and age of click-to-install, these programs will often require an additional install – I maintain that this should not be.

Most of these will be relevant to Linux, but the programs will often be missing on other commercial UNIXes also.

  • Ruby. This is the first that comes to mind. I have been installing ruby onto systems since 1.46 – and ruby is still a fantastic scripting language, and one of the best implementations of object-orientated programming since Smalltalk.
  • m4. I recently wrote about m4, and thought it was already installed on my Ubuntu Karmic system – not so. I used it to create a template for the APT sources.list file.
  • ssh. This should be installed everywhere automatically, and not as an add-on. For many UNIX systems, ssh is an add-on product that must be selected or compiled from source.
  • rsync. Rsync is a fabulous way to copy files across the network while minimizing traffic – even though it is not designed to be a fast way.
  • ksh. This will surprise most commercial UNIX administrators. However, Linux does not come with ksh installed – and the emulation by GNU bash is weak. Now you can install either AT&T ksh-93 (the newest version!) or the old standby, pdksh (which is close to ksh-88).

OpenVMS is a different animal – and some of the things that should be installed by default would be perl, ruby, java, SMH, and ssh. I’m not sure if perl or ssh is installed by default, but they should be. OpenVMS should also support compliant NFS v3 and v4 support out of the box – without making it difficult to connect to other NFS servers.

What programs do you think should be in the base install?

m4: 5 Places You Should Use It

The utility m4 is underutilized and underappreciated, and when paired with make can be indispensible. The mailer sendmail has made m4 legendary, and behind GNU autotools is a lot of serious m4 code. Why not use it for other purposes as well?

Here are some areas in which m4 can be used to ease your work:

  • cfengine. You can template the configuration of a “standard file” or a “standard directory” as m4 macros and save yourself a lot of typing (and errors). You could also define a standard “shell script” configuration and use m4 to create it every time.
  • Nagios. Nagios configurations benefit a lot from heavy use of m4. Macros can be used to template large configurations, and to template standard configurations.
  • DHCP server. A DHCP server can be set up to assign specific addresses to specific hosts; the configuration, however, can be tedious if there are more than a couple of hosts. Macros can be used to simplify static host configurations.
  • rpmrc. The /etc/rpmrc file is used to configure RPM during package build time. While not used as heavily, m4 can be used to create an rpmrc file specially tailored for the type of CPU running – this configuration will then be used when RPMs are built.
  • HTML generation. When creating hand-crafted HTML, m4 macros can simplify the creation of the standard tags, especially taking care of the beginning and ending tags transparently with only the content visible.

m4 makes templating easy. Anywhere that you need to set up a configuration with multiple sizable elements, m4 can help. A single m4 macro can expand to numerous configuration lines, and a couple dozen m4 lines can result in an extensive configuration set.

Using m4 macros in this manner prevents errors (because of less typing) and all appropriate configuration elements are the same (no mistaken copies).

m4 also adds “include” file capabilities to any configuration file where it is used. This permits common configurations to be reused everywhere, even though the configuration file may not support include files directly.

Even though make is not present on most system installs, m4 is. Adding make will complete this pair and set you on your way to automatic configuration. Try it today!

Configuring Nagios with m4

When using m4 to configure Nagios, great advantages can be realized.  One of the easiest places to gain an advantage by using m4 is when defining a new host.

Typically, a new host not only has a host definition but a number of fairly standardized services – such as ping, FTP, telnet, SSH, and so forth.  Thus, when defining a new host configuration, you not only have to add a new host, but all of the relevant services as well – and may also include host extra info and service extra info also.

#----------------------------------------
# HOST: marco
#----------------------------------------
define host{
        use                     hpux-host               ; Name of host template
        host_name               marco
        address                 192.168.4.1
        }
define hostextinfo{
        host_name               marco
        action_url              http://marco-mp/
}
define service{
        use                             passive-service          ; Name of servi
        host_name                       marco
        service_description             System Load
        servicegroups                   Load
        }
define service{
        use                             hpux-service          ; Name of service
        host_name                       marco
        service_description             PING
        check_command                   check_ping!100.0,20%!500.0,60%
        }
define service{
        use                             hpux-service          ; Name of service
        host_name                       marco
        service_description             TELNET
        servicegroups                   TELNET
        check_command                   check_telnet
        }
define serviceextinfo{
        host_name                       marco
        service_description             TELNET
        action_url                      telnet://marco
}
define service{
        use                             hpux-service          ; Name of service
        host_name                       marco
        service_description             FTP
        servicegroups                   FTP
        check_command                   check_ftp
        }
define service{
        use                             hpux-service          ; Name of service
        host_name                       marco
        service_description             NTP
        servicegroups                   NTP
        check_command                   check_ntp
        }
define service{
        use                             hpux-service          ; Name of service
        host_name                       marco
        service_description             SSH
        servicegroups                   SSH
        check_command                   check_ssh
        }

Compare that output from the m4 code that generated it:

DEFHPUX(`marco',`192.168.4.1')

Another benefit is that if DEFHPUX is coded correctly (with each service independent – such as an m4 macro DOSSH for SSH) – then a single change to the m4 file, propogated to the Nagios config file, can alter a service for every HP-UX host (in this example).

Here is a possible definition of DEFHPUX:

define(`DEFHPUX',`
#----------------------------------------
# HOST: $1
#----------------------------------------
define host{
        use                     hpux-host               ; Name of host template
        host_name               $1
        address                 $2
        }
define hostextinfo{
        host_name               $1
        action_url              http://$1-mp/
}'
DOLOAD(`$1')
DOPING(`$1')
DOTELNET(`$1')
DOFTP(`$1')
DONTP(`$1')
DOSSH(`$1')

There is a lot more that m4 can do; this is just the tip of the iceberg.

Powered by ScribeFire.

Nagios and m4

The macro processor m4 is perhaps one of the most underappreciated programs in a typical UNIX environment. Sendmail may be the only reason it still exists – or would that distinction include GNU autotools?

Configuring Nagios can be dramatically simplified and made easier using m4 with Nagios templates. Even when using Nagios service and host templates, there is a lot of repetition in the typical services file – perhaps an extreme amount of duplicated entries.

Using m4 can reduce the amount of work that is required to enter items.

Here is an example:

DEFHPUX(`red',`10.1.1.1')
DEFHPUX(`green',`10.1.1.2')
DEFHPUX(`blue',`10.1.1.3')
DEFHPUX(`white',`10.1.1.4')
DEFHPUX(`black',`10.1.1.5')
DEFHPUX(`orange',`10.1.1.6')

In my configuration, each line above expands into 64 lines (including three lines of header in the comments). So the result of those six lines is 384 lines of output.

Every DEFHPUX creates a host, complete with standard service checks such as PING, SSH, and TELNET. This is done all with just a few macro definitions at the beginning of the file.

Read about m4 and understand it, and your Nagios configurations will be much easier. You can use the program make to automate the creation of the actual config files and the check and reload necessary for Nagios to incorporate the changes.