Icinga1 configuration objects upgrader
This tool permits the conversion of Icinga1 configuration objects to a format compatible with Icinga2.
There is no one-to-one conversion method, so this tool attempts to make it as best as possible.
Installation
Using Debian package
The simple way is to retrieve and install the latest Debian package produced automatically for each release. See release page.
After downloading the latest Debian package, you can install it using the following command:
dpkg -i icinga1-objects-upgrader_1.0_all.deb
Using Python wheel package
On non-Debian based OS, you could also install the latest Python wheel package produced automatically for each release. See release page.
After downloading the latest Python wheel package, you can install it using the following command:
python3 -m pip install icinga1_objects_upgrader-1.0-py3-none-any.whl
From source
You could also manually install it from the source using Git:
git clone https://gitlab.easter-eggs.com/brenard/icinga1_objects_upgrader.git \
/usr/local/src/icinga1_objects_upgrader
python3 -m pip install /usr/local/bin/icinga1_objects_upgrader
Usage
usage: icinga1_objects_upgrader [-h] [-v] [-d] [-l LOGFILE] [-i INPUT] [-e INPUT_ENCODING]
[-o OUTPUT] [-E OUTPUT_ENCODING] [-m MAP_OBJECTS] [-D]
[--map-custom-macro MAP_CUSTOM_MACROS]
[--map-custom-user-macro-value MAP_CUSTOM_USER_MACRO_VALUES]
[--host-parents-mapping-policy {individual-dependency,variable}]
[--objects-mappers OBJECTS_MAPPERS] [--var-name-lowercase]
[-I IGNORE_UNSUPPORTED_PROPERTIES] [-x EXCLUDED_OBJECTS]
optional arguments:
-h, --help show this help message and exit
-v, --verbose Enable verbose mode
-d, --debug Enable debug mode
-l LOGFILE, --log-file LOGFILE
Log file path
-i INPUT, --input INPUT
Icinga object config directory path to parse
-e INPUT_ENCODING, --input-encoding INPUT_ENCODING
Encoding of Icinga1 object config files (default: utf-8)
-o OUTPUT, --output OUTPUT
Icinga object config directory path to parse
-E OUTPUT_ENCODING, --output-encoding OUTPUT_ENCODING
Encoding of Icinga2 object config files (default: utf-8)
-m MAP_OBJECTS, --map-object MAP_OBJECTS
Icinga1 objects name mapping for Icinga2. Could be use to map for
instance 'generic-debian' Icinga1 host template to Icinga2 'generic-
debian-pa2' Host template. For this example, you have to specify
--map-object host:generic-debian=generic-debian-pa2
-D, --map-object-display-name
Also map objects display name in Icinga2.
--map-custom-macro MAP_CUSTOM_MACROS
Icinga1 custom macro name mapping for Icinga2. Could be use to map
for instance '_NRPEPORT' Icinga1 host custom macro to Icinga2
'nrpe_port' host variable. For this example, you have to specify
--map-custom-macro NRPEPORT=nrpe_port
--map-custom-user-macro-value MAP_CUSTOM_USER_MACRO_VALUES
Icinga1 custom user macro value mapping for Icinga2. Could be use to
map for instance '$USER1$' Icinga1 custom user macro to
'/usr/lib/nagios/plugins' in Icinga2 configuration. For this
example, you have to specify --map-custom-user-macro-value
USER1=/usr/lib/nagios/plugins
--host-parents-mapping-policy {individual-dependency,variable}
Mapping policy for Icinga1 host parents: in Icinga2, host parents
have to be converted in host-to-host dependency. To do that, we
could simply create on host-to-parents dependency by host with
parents. Another way to do that, is to create an host variable that
will store the host's parents and apply host-to-parents by looping
on its variable values. This parameter permit to control the mapping
method you prefer: possible values are individual-dependency or
variable (default: individual-dependency). Note: with the variable
policy, only the hosts variable parents will be converted and you
have to manually add the apply Dependency rule (see
https://icinga.com/docs/icinga-2/latest/doc/23-migrating-from-
icinga-1x/#manual-config-migration-hints-for-host-parents).
--objects-mappers OBJECTS_MAPPERS
Icinga1 objects mappers: you could specify name of a python function
that will be call for each objects to permit custom adjustment on it
(for example, add some variables). For example, you could specify
'myicinga2.add_my_vars_to_host' to call the add_my_vars_to_host of
the python module myicinga2. This method will take the object
reference as unique parameter, could detect the object type using
the type object attribute and add some variables to the object
attribute variables (dict). Multiple objects mappers could be
specify by repeating this parameter.
--var-name-lowercase Put Icinga1 custom macro names in lowercase in Icinga2 configuration
-I IGNORE_UNSUPPORTED_PROPERTIES, --ignore-unsupported-property IGNORE_UNSUPPORTED_PROPERTIES
You could use this option to inhibate warnings about specified
unsupported properties. Multiple properties could be specified by
repeating this parameter.
-x EXCLUDED_OBJECTS, --exclude-object EXCLUDED_OBJECTS
This parameter could be use to exclude some Icinga1 objects that
will not be retrieved in Icinga2 configuration. For example, to
exclude the check_ipv6_ping command, you have to specify --exclude-
object command:check_ipv6_ping. Note: only the matching object will
be not exported, all references to this object will be keeped and
optionally map to another object if combine with -m/--map-object
parameter.
Example:
icinga1_objects_upgrader -v \
-i /etc/icinga1/objects -o /etc/icing2/conf.d \
--map-object command:check_ipv4_ping=ping4 \
--exclude-object command:check_ipv4_ping \
--map-object command:check_ipv4_host-alive=ping4 \
--exclude-object command:check_ipv4_host-alive \
--map-object command:check_smtp=smtp \
--map-object command:check_ssh=ssh \
--map-custom-macro SSHPORT=ssh_port \
--map-object command:check_http=http \
--map-object command:check_https=https \
--map-object command:check_simap=simap \
--map-object command:check_imap=imap \
--map-object command:check_spop=spop \
--map-object command:check_pop=pop \
--map-object command:check_ftp=ftp \
--map-object command:check_ssmtp=ssmtp \
--map-object command:check_ipv6_ping=ping6 \
--exclude-object command:check_ipv6_ping \
--map-object command:check_ipv6_host-alive=hostalive6 \
--exclude-object command:check_ipv6_host-alive \
--map-custom-user-macro-value USER1=/usr/lib/nagios/plugins \
--var-name-lowercase \
--map-object-display-name \
--ignore-unsupported-property host_notification_commands \
--ignore-unsupported-property service_notification_commands \
--ignore-unsupported-property inherits_parent \
--ignore-unsupported-property notification_failure_criteria \
--host-parents-mapping-policy variable
Define notifications
More than any other concept, notifications have been completely redesigned in Icinga2, and it's really not possible to convert them one-to-one:
- contact and contactgroup are now User and UserGroup objects.
- There are no notification parameters in Host and Service definitions (except for the _enablenotifications parameter).
- User's notification parameters have changed significantly:
- _host_notificationsenabled and _service_notificationsenabled parameters are replaced by a single _enablenotifications parameter.
- _host_notificationperiod and _service_notificationperiod parameters are replaced by a single period parameter.
- _host_notificationoptions and _service_notificationoptions parameters are replaced by similar states and types parameters.
- _host_notificationcommands and _service_notificationcommands parameters are removed, and notification commands are now defined in the Notification object.
- Notification objects now group parameters about notifications sent to users.
To make migration easier, I am trying to implement a solution for migrating configurations. I've placed old contacts, _contactgroups, _notificationinterval, _notificationperiod, _notificationsoptions, and _first_notificationdelay of Host and Service objects into a notifications variable. This allows us to dynamically configure Notification objects. The following example demonstrates how to send email notifications to users:
template Notification "generic-notification" {
period = "24x7"
interval = 1h
types = [ Problem, Acknowledgement, Recovery, Custom, FlappingStart,
FlappingEnd, DowntimeStart, DowntimeEnd, DowntimeRemoved ]
users = [ "icingaadmin" ]
}
template Notification "generic-host-notification" {
import "generic-notification"
command = "mail-host-notification"
if (host.vars.notifications.users || host.vars.notifications.groups) {
if (host.vars.notifications.users) {
users = host.vars.notifications.users
} else {
users = []
}
if (host.vars.notifications.groups) {
user_groups = host.vars.notifications.groups
} else {
user_groups = []
}
}
if (host.vars.notifications.states) {
states = host.vars.notifications.states
} else {
states = [ Up, Down ]
}
if (host.vars.notifications.types) {
types = host.vars.notifications.types
}
if (host.vars.notifications.period) {
period = host.vars.notifications.period
}
if (host.vars.notifications.interval) {
interval = host.vars.notifications.interval
}
if (host.vars.notifications.delay) {
times.begin = host.vars.notifications.delay
}
}
template Notification "generic-service-notification" {
import "generic-notification"
command = "mail-service-notification"
if (service.vars.notifications.users || service.vars.notifications.groups) {
if (service.vars.notifications.users) {
users = service.vars.notifications.users
} else {
users = []
}
if (service.vars.notifications.groups) {
user_groups = service.vars.notifications.groups
} else {
user_groups = []
}
}
if (service.vars.notifications.states) {
states = service.vars.notifications.states
} else {
states = [ Warning, Critical, Unknown ]
}
if (service.vars.notifications.types) {
types = service.vars.notifications.types
}
if (service.vars.notifications.period) {
period = service.vars.notifications.period
}
if (service.vars.notifications.interval) {
interval = service.vars.notifications.interval
}
if (service.vars.notifications.delay) {
times.begin = service.vars.notifications.delay
}
}
apply Notification "notify-by-mail" to Host {
import "generic-host-notification"
assign where match("*", host.name) && host.enable_notifications
}
apply Notification "notify-by-mail" to Service {
import "generic-service-notification"
assign where match("*", service.name) && service.enable_notifications
}
Note:
- https://icinga.com/docs/icinga2/latest/doc/23-migrating-from-icinga-1x/#manual-config-migration-hints-for-notifications
- https://icinga.com/docs/icinga2/latest/doc/03-monitoring-basics/#notifications-users-from-hostservice
Copyright
Copyright (c) 2020-2022 Benjamin Renard / Easter-eggs
License
This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License version 3 as published by the Free Software Foundation.
This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.