Mapping hostnames to locations with Icinga Director

by | Aug 2, 2023

Recently I came across the Maps module build and maintained by our community. The module displays host objects and annotations on openstreetmap using the JavaScript library leaflet.js. The module reads the coordinates for each host from custom variables and is able to group multiple hosts on the same location.

There is already a guide on our blog that describes how you can use the module with human readable locations instead of numeric geolocations. My goal was to use a similar approach, but configure it through Icinga Director instead of plain configuration files. In addition, I wanted to import the hosts from a database and at the same time automatically add their geolocation based on the hostname. Here’s the final config I came up with.

The hostnames in my scenario follow a certain naming schema. This allowed me to use the first four letters to identify their location. The hostnames looked something similar to this:

AZBPxyz.dummy.com
COBOabc.dummy.com
USCYabc.dummy.com

Creating DataLists

First of all I created some DataLists to map the shortcodes (first 4 letters of the hostname) with a human readable location. And another DataList to map the readable location with the actual geolocation that can be used by the Maps module.

GeoLocationShort: Here we map the shortcode to the name of the city:

Geolocation: Here we map the city with the coordinates

This would already allow me to manually assign the location when creating new hosts. For example, the DataLists can be used in Host Templates to set some sane defaults. However, my goal was to do this automatically based on the hostname. My next step is to create an import source.

Creating an Import Source

Icinga Director offers very powerful mechanisms when it comes to fetching data from external data sources. By defining an Import Source you basically teach the Director how to connect to a third-party database and collect data and create Icinga configuration out of it. There are plenty of different Import Source types available, such as MySQL, PostgreSQL, LDAP, Active Directory, CSV files and more. For my demo I created a very simple MySQL database with a single table. I only added the hostnames and an IP address. Of course this table could include much more information.

+-------------------+-----------+
| hostname          | address   |
+-------------------+-----------+
| AZBPxyz.dummy.com | 127.0.0.1 |
| COBOabc.dummy.com | 127.0.0.2 |
| USCYabc.dummy.com | 127.0.0.3 |
+-------------------+-----------+

 

The SQL query I used to fetch the data is very simple as well: SELECT hosts_map.hostname, hosts_map.address FROM dummy_hosts.hosts_map; This will collect the hostname and the IP address of each host and make it available for you to create Icinga hosts out of this information.

Adding property modifiers to the Import Source

Now that I can import the hostnames, my next step is to extract the first four letter out of the name and use it to assign custom variables that contain information about the location of the host. Data sources like SQL databases provide very powerful modifiers themselves. With a handcrafted query you can solve lots of data conversion problems. Sometimes this is not possible, and some sources (like LDAP) do not even have such features. Therefore, I’m using the build-in property modifiers of Icinga Director. This allows me to use the same mechanism even if my source is not SQL, but also provides more transparency and it’s easier for other to understand what’s going on here. I added three modifiers to my Import Source:

The first modifier extracts the first 4 characters and writes them into a custom variable called “geolocation-short”. I’m using the regular expression based replacement to achieve this.

 

The second modifier maps the shortcode from the custom variable geolocation-short with the DataList “GeolocationShort” to get the city name. It writes the city into a custom variable called “geolocation-long”

 

The third modifier finally maps the city name with the coordinates by using the DataList “GeoLocation”. The result is written into the custom variable geolocation
(3-modifier-geolocation.png)

Beware: The ordering of those modifiers is important!

The result

The result is as following: You get 3 custom variables for each imported host definition. I’m aware that I could use less custom variable to do the mapping, but I did it this way intentionally because it gives you a nice overview when looking at the hosts later.

  • geolocation-short The shortcode as a result from the hostname
  • geolocation-long Readable name of the location
  • geolocation Coordinates as used by the maps module

 

Follow up

The import source alone won’t create any Icinga configuration of course. With Sync Rules you can use the data provided by Import Sources and actually create a configuration out of it.

You May Also Like…

Code Reviews – How do they work?

Code Reviews – How do they work?

We at Icinga / NETWAYS (yes, that’s the order) held an internal event recently. It’s name was Knowledge Days and I got...

Subscribe to our Newsletter

A monthly digest of the latest Icinga news, releases, articles and community topics.