In this recipe, you'll learn one possible method of building Nagios configuration dynamically to avoid having to compose or copy and paste a lot of directives for new hosts or services. In other words, this recipe is about generating a configuration using templates.
To demonstrate how this is useful, we'll use the m4 macro language utility, which should be available on virtually any UNIX-like system, including GNU/Linux and BSD. As a tool designed for macro expansion, m4 is particularly well suited to creating verbose plain text configuration files, such as the ones used by Nagios Core.
The principles here should apply just as easily to your favored programming or templating language, perhaps Python, Perl, or shell scripts.
You will need to have the m4(1)
macro language tool available to you, preferably but not necessarily on the same system as the one running Nagios Core. It is a very standard tool and should be already installed or available as part of a package. The version used in this example is GNU m4(1)
, documented at http://www.gnu.org/software/m4/manual/m4.html. This recipe does not assume any familiarity with m4
and will show you the basics.
You may like to work in a new subdirectory in your home directory; run the following code for this:
$ mkdir $HOME/nagios-dynamic-hosts $ cd $HOME/nagios-dynamic-hosts
We can create and apply an example Nagios Core configuration template like so:
host-service-template.m4
with the following contents:define(`NAGHOST', ` define host { host_name $1 alias $2 address $3 contact_groups ifelse(`$#', `4', `$4', `admins') check_command check-host-alive check_interval 5 check_period 24x7 max_check_attempts 3 notification_interval 30 notification_options d,r notification_period 24x7 } define service { host_name $1 contact_groups ifelse(`$#', `4', `$4', `admins') check_command check_ping!100,10%!200,20% check_interval 5 check_period 24x7 max_check_attempts 3 notification_interval 30 notification_period 24x7 retry_interval 1 service_description PING } ')
sparta.host.m4
with the following contents:include(`host-service-template.m4') NAGHOST(`sparta', `Sparta Webserver', `192.0.2.21')
athens.host.m4
with the following contents:include(`host-service-template.m4') NAGHOST(`athens', `Athens Webserver', `192.0.2.22', `ops')
$ m4 sparta.host.m4 define host { host_name sparta alias Sparta Webserver address 192.0.2.21 contact_groups admins check_command check-host-alive check_interval 5 check_period 24x7 max_check_attempts 3 notification_interval 30 notification_options d,r notification_period 24x7 } define service { host_name sparta contact_groups admins check_command check_ping!100,10%!200,20% check_interval 5 check_period 24x7 max_check_attempts 3 notification_interval 30 notification_period 24x7 retry_interval 1 service_description PING } $ m4 athens.host.m4 define host { host_name athens alias Athens Webserver address 192.0.2.22 contact_groups ops check_command check-host-alive check_interval 5 check_period 24x7 max_check_attempts 3 notification_interval 30 notification_options d,r notification_period 24x7 } define service { host_name athens contact_groups ops check_command check_ping!100,10%!200,20% check_interval 5 check_period 24x7 max_check_attempts 3 notification_interval 30 notification_period 24x7 retry_interval 1 service_description PING }
As seen in the preceding output, we can now generate a basic host and service configuration with a two-line m4 script referring to a template simply by writing the output to a .cfg
file. Take a look at this line:
$ m4 sparta.host.m4 > sparta.cfg
The sparta.host.m4
and athens.host.m4
files both called an m4 macro with arguments after including the template for the host and service in the host-service-template.m4
file. This was expanded into the full definition and the arguments given were substituted as follows:
$1
was replaced with the first argument, host_name
$2
was replaced with the second argument, alias
$3
was replaced with the third argument, address
$4
was replaced with the fourth argument, contact_group
Note that two of these values, $1
and $4
, were used in both the host and the PING
service definitions.
Also, note that the $4
argument is optional; the ifelse
construct tests the number of arguments and, if it finds that there are four, it uses the value of the fourth argument. For athens.example.net
, this is the contact group ops
. If there is no fourth argument, it defaults instead to the admins
value. This allows us to set default values for arguments if we so choose.
The rest of the directives are all written directly into the template. The configuration made by this process is valid for Nagios Core, assuming the check_command
and contact_groups
used are defined.
To automate things even further, we could use make(1)
to automatically generate .cfg
files from anything with the .host.m4
extension with the following Makefile
syntax:
%.cfg : %.host.m4 m4 $< > $*.cfg
With this in the same directory as all the preceding files, in order to build the configuration for the sparta.example.net
host, we would only need a call to make(1)
to generate the file, as follows:
$ make sparta.cfg m4 sparta.host.m4 > sparta.cfg $ make athens.cfg m4 athens.host.m4 > athens.cfg
Note that it's best practice to avoid repeating directives and use hostgroups and host and service templates instead to define "roles" for new hosts. This makes adding and removing the hosts much easier and both the processes are explained in this chapter in the Configuring host roles using groups and Using inheritance to simplify configuration recipes. Mei Douthitt goes into considerably more depth about the possibilities of using m4 for Nagios configuration at http://administratosphere.wordpress.com/2009/02/19/configuring-nagios-with-m4/.
52.15.74.25