mirror of https://github.com/Icinga/icinga2.git
Refactor config migration script, install as /usr/sbin/icinga2-migrate-config
fixes #4696
This commit is contained in:
parent
c0c7f485ad
commit
99874a9eee
|
@ -192,6 +192,7 @@ third-party/cJSON/Makefile
|
|||
third-party/execvpe/Makefile
|
||||
third-party/mmatch/Makefile
|
||||
tools/Makefile
|
||||
tools/migration/Makefile
|
||||
tools/i2enfeature
|
||||
tools/mkembedconfig/Makefile
|
||||
])
|
||||
|
|
|
@ -26,8 +26,7 @@ possible.
|
|||
> Please check the provided README file for additional notes and possible
|
||||
> scaveats.
|
||||
|
||||
# cd tools/configconvert
|
||||
# ./icinga2_convert_v1_v2.pl -c /etc/icinga/icinga.cfg -o conf/
|
||||
# /usr/sbin/icinga2-migrate-config -c /etc/icinga/icinga.cfg -o conf/
|
||||
|
||||
|
||||
### Manual Config Conversion
|
||||
|
|
|
@ -215,6 +215,7 @@ fi
|
|||
%{_bindir}/%{name}
|
||||
%{_sbindir}/i2enfeature
|
||||
%{_sbindir}/i2disfeature
|
||||
%{_sbindir}/icinga2-migrate-config
|
||||
%exclude %{_libdir}/%{name}/libdb_ido_mysql*
|
||||
%{_libdir}/%{name}
|
||||
%{_datadir}/doc/%{name}
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
SUBDIRS = \
|
||||
mkembedconfig
|
||||
migration \
|
||||
mkembedconfig
|
||||
|
||||
sbin_SCRIPTS = i2enfeature
|
||||
CLEANFILES = $(bin_SCRIPTS)
|
||||
|
|
|
@ -1,35 +0,0 @@
|
|||
|
||||
=pod
|
||||
/******************************************************************************
|
||||
* Icinga 2 *
|
||||
* Copyright (C) 2012-2013 Icinga Development Team (http://www.icinga.org/) *
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or *
|
||||
* modify it under the terms of the GNU General Public License *
|
||||
* as published by the Free Software Foundation; either version 2 *
|
||||
* of the License, or (at your option) any later version. *
|
||||
* *
|
||||
* 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
|
||||
******************************************************************************/
|
||||
=cut
|
||||
|
||||
package Icinga2;
|
||||
|
||||
use strict;
|
||||
|
||||
# GLOBAL definitions
|
||||
#
|
||||
#
|
||||
|
||||
|
||||
1;
|
||||
|
||||
__END__
|
||||
# vi: sw=4 ts=4 expandtab :
|
File diff suppressed because it is too large
Load Diff
|
@ -1,309 +0,0 @@
|
|||
|
||||
=pod
|
||||
/******************************************************************************
|
||||
* Icinga 2 *
|
||||
* Copyright (C) 2012-2013 Icinga Development Team (http://www.icinga.org/) *
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or *
|
||||
* modify it under the terms of the GNU General Public License *
|
||||
* as published by the Free Software Foundation; either version 2 *
|
||||
* of the License, or (at your option) any later version. *
|
||||
* *
|
||||
* 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
|
||||
******************************************************************************/
|
||||
=cut
|
||||
|
||||
|
||||
package Icinga2::ImportIcinga1Cfg;
|
||||
|
||||
push (@INC, 'pwd');
|
||||
|
||||
use strict;
|
||||
use Data::Dumper;
|
||||
use File::Find;
|
||||
use Storable qw(dclone);
|
||||
|
||||
use feature 'say';
|
||||
|
||||
#use Icinga2;
|
||||
use Icinga2::Utils;
|
||||
|
||||
|
||||
################################################################################
|
||||
# PARSE 1.x
|
||||
################################################################################
|
||||
|
||||
sub get_key_from_icinga1_main_cfg {
|
||||
my ($file, $key) = @_;
|
||||
|
||||
my @key_arr = ();
|
||||
|
||||
if ( !-f $file) {
|
||||
print "cfg file $file does not exist!";
|
||||
return;
|
||||
}
|
||||
|
||||
if ( open ( my $fh, '<', $file ) ) {
|
||||
while ( my $line = <$fh> ) {
|
||||
chomp($line);
|
||||
$line =~ s/#.*//;
|
||||
if ($line =~ /^\s*$key=([^\s]+)/) {
|
||||
push @key_arr, $1; # we may have multiple occurences
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return @key_arr;
|
||||
}
|
||||
|
||||
sub parse_icinga1_resource_cfg {
|
||||
my $file = shift;
|
||||
|
||||
my @cfg = Icinga2::Utils::slurp($file);
|
||||
|
||||
my $global_macros = {};
|
||||
|
||||
foreach my $line (@cfg) {
|
||||
$line = Icinga2::Utils::strip($line);
|
||||
|
||||
# skip comments and empty lines
|
||||
next if ($line eq "" || !defined($line) || $line =~ /^\s+$/);
|
||||
next if ($line =~ /^[#;]/ || $line =~ /;.*/);
|
||||
|
||||
#debug($line);
|
||||
my ($macro_name, $macro_value) = split /=/, $line, 2;
|
||||
$macro_name =~ /\$(.*)\$/;
|
||||
$macro_name = $1;
|
||||
|
||||
$global_macros->{$macro_name} = Icinga2::Utils::escape_str($macro_value);
|
||||
}
|
||||
|
||||
return $global_macros;
|
||||
|
||||
}
|
||||
|
||||
sub parse_icinga1_global_macros {
|
||||
my $icinga1_cfg = shift;
|
||||
|
||||
my ($icinga1_resource_file) = get_key_from_icinga1_main_cfg($icinga1_cfg, "resource_file");
|
||||
|
||||
# resource.cfg
|
||||
my $global_macros = parse_icinga1_resource_cfg($icinga1_resource_file);
|
||||
|
||||
# special attributes in icinga.cfg (admin_*)
|
||||
my ($admin_pager) = get_key_from_icinga1_main_cfg($icinga1_cfg, "admin_pager");
|
||||
my ($admin_email) = get_key_from_icinga1_main_cfg($icinga1_cfg, "admin_email");
|
||||
|
||||
$global_macros->{'ADMINPAGER'} = $admin_pager;
|
||||
$global_macros->{'ADMINEMAIL'} = $admin_email;
|
||||
|
||||
return $global_macros;
|
||||
}
|
||||
|
||||
sub parse_icinga1_object_cfg {
|
||||
my $cfg_obj = shift;
|
||||
my $file = shift;
|
||||
|
||||
my $obj = {}; #hashref
|
||||
my $in_define = 0;
|
||||
my $in_timeperiod = 0;
|
||||
my $type;
|
||||
my $append; # this is a special case where multiple lines are appended with \ - not sure if we support THAT.
|
||||
my $inline_comment;
|
||||
|
||||
my $attr;
|
||||
my $val;
|
||||
|
||||
my @cfg = Icinga2::Utils::slurp($file);
|
||||
|
||||
#Icinga2::Utils::debug("========================================================");
|
||||
#Icinga2::Utils::debug("File: $file");
|
||||
foreach my $line (@cfg) {
|
||||
$line = Icinga2::Utils::strip($line);
|
||||
|
||||
#Icinga2::Utils::debug("Processing line: '$line'");
|
||||
|
||||
# skip comments and empty lines
|
||||
next if ($line eq "" || !defined($line) || $line =~ /^\s+$/);
|
||||
next if ($line =~ /^[#;]/);
|
||||
|
||||
# || $line =~ /;.*/);
|
||||
$line =~ s/[\r\n\s]+$//;
|
||||
$line =~ s/^\s+//;
|
||||
|
||||
# end of def
|
||||
if ($line =~ /}(\s*)$/) {
|
||||
$in_define = undef;
|
||||
# store type for later
|
||||
$cfg_obj->{'type_cnt'}->{$type} = $cfg_obj->{'type_cnt'}->{$type} + 1;
|
||||
$type = "";
|
||||
next;
|
||||
}
|
||||
# start of def
|
||||
elsif ($line =~ /define\s+(\w+)\s*{?(.*)$/) {
|
||||
$type = $1;
|
||||
$append = $2;
|
||||
if ($type eq "timeperiod") {
|
||||
$in_timeperiod = 1;
|
||||
} else {
|
||||
$in_timeperiod = 0;
|
||||
}
|
||||
|
||||
# save the type
|
||||
$cfg_obj->{$type}->{$cfg_obj->{'type_cnt'}->{$type}}->{'__I2CONVERT_TYPE'} = $type;
|
||||
|
||||
# we're ready to process entries
|
||||
$in_define = 1;
|
||||
# save the current type counter, being our unique key here
|
||||
next;
|
||||
}
|
||||
# in def
|
||||
elsif ($in_define == 1) {
|
||||
|
||||
# first, remove the annoying inline comments after ';'
|
||||
$line =~ s/\s*[;\#](.*)$//;
|
||||
$inline_comment = $1;
|
||||
|
||||
# then split it and save it by type->cnt->attr->val
|
||||
#($attr, $val) = split (/\s+/, $line, 2); # important - only split into 2 elements
|
||||
|
||||
# timeperiods require special parser
|
||||
if ($in_timeperiod == 1) {
|
||||
if ($line =~ /timeperiod_name/ || $line =~ /alias/ || $line =~ /exclude/) {
|
||||
$line =~ m/([\w]+)\s*(.*)/;
|
||||
$attr = Icinga2::Utils::strip($1); $val = Icinga2::Utils::strip($2);
|
||||
} else {
|
||||
$line =~ m/(.*)\s+([\d\W]+)/;
|
||||
$attr = Icinga2::Utils::strip($1); $val = Icinga2::Utils::strip($2);
|
||||
}
|
||||
} else {
|
||||
$line =~ m/([\w]+)\s*(.*)/;
|
||||
$attr = Icinga2::Utils::strip($1); $val = Icinga2::Utils::strip($2);
|
||||
}
|
||||
# ignore empty values
|
||||
next if (!defined($val));
|
||||
next if ($val eq "");
|
||||
#Icinga2::Utils::debug("cnt: $cfg_obj->{'type_cnt'}->{$type}");
|
||||
#Icinga2::Utils::debug("line: '$line'");
|
||||
#Icinga2::Utils::debug("type: $type");
|
||||
#Icinga2::Utils::debug("attr: $attr");
|
||||
#Icinga2::Utils::debug("val: $val");
|
||||
#Icinga2::Utils::debug("\n");
|
||||
|
||||
# strip illegal object name characters, replace with _
|
||||
if ( ($attr =~ /name/ && $attr !~ /display_name/) ||
|
||||
$attr =~ /description/ ||
|
||||
$attr =~ /contact/ ||
|
||||
$attr =~ /groups/ ||
|
||||
$attr =~ /members/ ||
|
||||
$attr =~ /use/ ||
|
||||
$attr =~ /parents/
|
||||
) {
|
||||
$val = Icinga2::Utils::strip_object_name($val);
|
||||
}
|
||||
# treat 'null' (disable) as '0'
|
||||
if ($val eq "null") {
|
||||
$val = 0;
|
||||
}
|
||||
|
||||
$cfg_obj->{$type}->{$cfg_obj->{'type_cnt'}->{$type}}->{$attr} = $val;
|
||||
|
||||
# ignore duplicated attributes, last one wins
|
||||
}
|
||||
else {
|
||||
$in_define = 0;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#Icinga2::Utils::debug("========================================================");
|
||||
|
||||
return $cfg_obj;
|
||||
|
||||
}
|
||||
|
||||
# the idea is to reduce work load - get all the existing object relations (host->service)
|
||||
# and have core 1.x already mapped that. we focus on getting the details when
|
||||
# needed, but do not print the object without templates - only if there's no other way.
|
||||
sub parse_icinga1_objects_cache {
|
||||
my $icinga1_cfg = shift;
|
||||
|
||||
# XXX not needed right now
|
||||
return undef;
|
||||
|
||||
# functions return array in case of multiple occurences, we'll take only the first one
|
||||
my ($object_cache_file) = get_key_from_icinga1_main_cfg($icinga1_cfg, "object_cache_file");
|
||||
|
||||
if(!defined($object_cache_file)) {
|
||||
print "ERROR: No objects cache file found in $icinga1_cfg! We'll need for final object conversion.\n";
|
||||
return -1;
|
||||
}
|
||||
|
||||
if(! -r $object_cache_file) {
|
||||
print "ERROR: objects cache file '$object_cache_file' from $icinga1_cfg not found! We'll need it for final object conversion.\n";
|
||||
return -1;
|
||||
}
|
||||
|
||||
my $cfg_obj_cache = {};
|
||||
|
||||
$cfg_obj_cache = parse_icinga1_object_cfg($cfg_obj_cache, $object_cache_file);
|
||||
|
||||
#say Dumper($cfg_obj_cache);
|
||||
|
||||
return $cfg_obj_cache;
|
||||
|
||||
}
|
||||
|
||||
# parse all existing config object included in icinga.cfg, with all their templates
|
||||
# and grouping tricks
|
||||
sub parse_icinga1_objects {
|
||||
my $icinga1_cfg = shift;
|
||||
|
||||
my @cfg_files = get_key_from_icinga1_main_cfg($icinga1_cfg, "cfg_file");
|
||||
my @cfg_dirs = get_key_from_icinga1_main_cfg($icinga1_cfg, "cfg_dir");
|
||||
|
||||
sub find_icinga1_cfg_files {
|
||||
my $file = $File::Find::name;
|
||||
return if -d $file;
|
||||
if ($file =~ /\.cfg$/) {
|
||||
push @cfg_files, $file;
|
||||
}
|
||||
}
|
||||
|
||||
foreach my $cfg_dir (@cfg_dirs) {
|
||||
find(\&find_icinga1_cfg_files, $cfg_dir);
|
||||
}
|
||||
|
||||
# check if there was nothing to include
|
||||
if (!@cfg_files) {
|
||||
print "ERROR: $icinga1_cfg did not contain any object includes.\n";
|
||||
return -1;
|
||||
}
|
||||
#print "@cfg_files";
|
||||
|
||||
# now fetch all the config information into our global hash ref
|
||||
my $cfg_objs = {};
|
||||
|
||||
foreach my $cfg_file (@cfg_files) {
|
||||
print "Processing file '$cfg_file'...\n";
|
||||
$cfg_objs = parse_icinga1_object_cfg($cfg_objs, $cfg_file);
|
||||
}
|
||||
|
||||
#say Dumper($cfg_obj);
|
||||
#say Dumper($cfg_obj->{'service'});
|
||||
|
||||
return $cfg_objs;
|
||||
}
|
||||
|
||||
|
||||
1;
|
||||
|
||||
__END__
|
||||
# vi: sw=4 ts=4 expandtab :
|
|
@ -1,139 +0,0 @@
|
|||
|
||||
=pod
|
||||
/******************************************************************************
|
||||
* Icinga 2 *
|
||||
* Copyright (C) 2012-2013 Icinga Development Team (http://www.icinga.org/) *
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or *
|
||||
* modify it under the terms of the GNU General Public License *
|
||||
* as published by the Free Software Foundation; either version 2 *
|
||||
* of the License, or (at your option) any later version. *
|
||||
* *
|
||||
* 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
|
||||
******************************************************************************/
|
||||
=cut
|
||||
|
||||
|
||||
package Icinga2::Utils;
|
||||
|
||||
use strict;
|
||||
#use Icinga2;
|
||||
|
||||
our $dbg_lvl;
|
||||
|
||||
################################################################################
|
||||
# HELPER FUNCTIONS
|
||||
################################################################################
|
||||
|
||||
sub strip {
|
||||
my $str = shift;
|
||||
|
||||
#strip trailing and leading whitespaces
|
||||
$str =~ s/^\s+//;
|
||||
$str =~ s/\s+$//;
|
||||
|
||||
return $str;
|
||||
}
|
||||
|
||||
sub errlog {
|
||||
my $err_lvl = shift;
|
||||
my $log_str = shift;
|
||||
|
||||
if ($err_lvl > 0) {
|
||||
print STDERR color("red"), "$log_str\n";;
|
||||
} else {
|
||||
print "$log_str\n";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
sub escape_str {
|
||||
my $str = shift;
|
||||
|
||||
$str =~ s/"/\\"/g;
|
||||
$str =~ s/\\\\"/\\"/g;
|
||||
|
||||
return $str;
|
||||
}
|
||||
sub escape_shell_meta {
|
||||
my $str = shift;
|
||||
|
||||
$str =~ s/([;<>`'":&!#\$\[\]\{\}\(\)\*\|])/\\$1/g;
|
||||
return $str;
|
||||
}
|
||||
|
||||
sub debug {
|
||||
my $dbg_str = shift;
|
||||
our $dbg_lvl;
|
||||
|
||||
if ($dbg_lvl > 0) {
|
||||
print "$dbg_str\n";
|
||||
}
|
||||
}
|
||||
|
||||
sub slurp {
|
||||
my $file = shift;
|
||||
|
||||
if ( -f $file ) {
|
||||
open ( my $fh, "<", $file ) or die "Could not open $file: $!";
|
||||
return do {
|
||||
<$fh>;
|
||||
}
|
||||
} elsif (! -r $file) {
|
||||
print " ERROR: $file not readable. check permissions/user!\n"
|
||||
} else {
|
||||
print " ERROR: $file does not exist\n";
|
||||
}
|
||||
}
|
||||
|
||||
# stolen from http://stackoverflow.com/questions/7651/how-do-i-remove-duplicate-items-from-an-array-in-perl
|
||||
sub uniq {
|
||||
return keys %{{ map { $_ => 1 } @_ }};
|
||||
}
|
||||
|
||||
sub str2arr_by_delim_without_excludes {
|
||||
my $str = shift;
|
||||
my $delim = shift;
|
||||
my $sort = shift;
|
||||
my $exclude = shift;
|
||||
my @arr = ();
|
||||
|
||||
@arr = map { s/^\s+//; s/\s+$//; $_ }
|
||||
grep { !/^!/ }
|
||||
split (/$delim/, $str);
|
||||
|
||||
if ($sort == 1) {
|
||||
@arr = sort (@arr);
|
||||
}
|
||||
|
||||
return @arr;
|
||||
}
|
||||
|
||||
sub strip_object_name {
|
||||
my $obj_str = shift;
|
||||
|
||||
#$obj_str =~ s/[`~!\\\$%\^&\*|'"<>\?,\(\)=:]/_/g;
|
||||
$obj_str =~ s/[:]/_/g;
|
||||
|
||||
return $obj_str;
|
||||
}
|
||||
|
||||
sub print_sorted_hash {
|
||||
my $hash = shift;
|
||||
|
||||
foreach my $key (sort keys %{$hash}) {
|
||||
print "$key = $hash->{$key}\n";
|
||||
}
|
||||
}
|
||||
|
||||
1;
|
||||
|
||||
__END__
|
||||
# vi: sw=4 ts=4 expandtab :
|
|
@ -1,243 +0,0 @@
|
|||
#!/usr/bin/perl
|
||||
|
||||
=pod
|
||||
/******************************************************************************
|
||||
* Icinga 2 *
|
||||
* Copyright (C) 2012-2013 Icinga Development Team (http://www.icinga.org/) *
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or *
|
||||
* modify it under the terms of the GNU General Public License *
|
||||
* as published by the Free Software Foundation; either version 2 *
|
||||
* of the License, or (at your option) any later version. *
|
||||
* *
|
||||
* 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
|
||||
******************************************************************************/
|
||||
=cut
|
||||
|
||||
=head1 NAME
|
||||
|
||||
icinga2_convert_v1_v2.pl - convert icinga 1.x config to icinga 2.x format
|
||||
|
||||
=head1 SYNOPSIS
|
||||
|
||||
icinga2_convert_v1_v2.pl -c <path to icinga.cfg>
|
||||
-o <output directory for icinga2 config>
|
||||
[-v]
|
||||
[-h]
|
||||
[-V]
|
||||
|
||||
Convert Icinga 1.x configuration to new Icinga 2.x configuration format.
|
||||
|
||||
=head1 OPTIONS
|
||||
|
||||
=over
|
||||
|
||||
=item -c|--icingacfgfile <path to icinga.cfg>
|
||||
|
||||
Path to your Icinga 1.x main configuration file "icinga.cfg".
|
||||
|
||||
=item -o|--outputcfgdir <output directory for icinga2 config>
|
||||
|
||||
Directory to Icinga 2.x configuration output.
|
||||
|
||||
=item --hosttmpl=<template name>
|
||||
|
||||
Custom template name for all host objects.
|
||||
|
||||
=item --servicetmpl=<template name>
|
||||
|
||||
Custom template name for all service objects.
|
||||
|
||||
=item --usertmpl=<template name>
|
||||
|
||||
Custom template name for all user objects.
|
||||
|
||||
=item --timeperiodtmpl=<template name>
|
||||
|
||||
Custom template name for all timeperiod objects.
|
||||
|
||||
=item --notificationtmpl=<template name>
|
||||
|
||||
Custom template name for all notification objects.
|
||||
|
||||
=item --checkcommandtmpl=<template name>
|
||||
|
||||
Custom template name for all checkcommand objects.
|
||||
|
||||
=item --notificationcommandtmpl=<template name>
|
||||
|
||||
Custom template name for all notificationcommand objects.
|
||||
|
||||
=item --eventcommandtmpl=<template name>
|
||||
|
||||
Custom template name for all eventcommand objects.
|
||||
|
||||
=item -v|--verbose
|
||||
|
||||
Verbose mode.
|
||||
|
||||
=item -h|--help
|
||||
|
||||
Print help page.
|
||||
|
||||
=item -V|--version
|
||||
|
||||
print version.
|
||||
|
||||
=cut
|
||||
|
||||
use warnings;
|
||||
use strict;
|
||||
|
||||
use Data::Dumper;
|
||||
use File::Find;
|
||||
use Storable qw(dclone);
|
||||
use Getopt::Long qw(:config no_ignore_case bundling);
|
||||
use Pod::Usage;
|
||||
|
||||
use feature 'say';
|
||||
|
||||
push @INC, 'pwd';
|
||||
use Icinga2::ImportIcinga1Cfg;
|
||||
use Icinga2::ExportIcinga2Cfg;
|
||||
use Icinga2::Convert;
|
||||
use Icinga2::Utils;
|
||||
|
||||
my $version = "0.0.1";
|
||||
|
||||
# get command-line parameters
|
||||
our $opt;
|
||||
GetOptions(
|
||||
"c|icingacfgfile=s" => \$opt->{icinga1xcfg},
|
||||
"o|outputcfgdir=s" => \$opt->{icinga2xoutputprefix},
|
||||
"hosttmpl=s" => \$opt->{hosttmpl},
|
||||
"servicetmpl=s" => \$opt->{servicetmpl},
|
||||
"usertmpl=s" => \$opt->{usertmpl},
|
||||
"notificationtmpl=s" => \$opt->{notificationtmpl},
|
||||
"timeperiodtmpl=s" => \$opt->{timeperiodtmpl},
|
||||
"checkcommandtmpl=s" => \$opt->{checkcommandtmpl},
|
||||
"notificationcommandtmpl=s" => \$opt->{notificationcommandtmpl},
|
||||
"eventcommandtmpl=s" => \$opt->{eventcommandtmpl},
|
||||
"tmpl=s" => \$opt->{tmpl},
|
||||
"tmpl=s" => \$opt->{tmpl},
|
||||
"v|verbose" => \$opt->{verbose},
|
||||
"h|help" => \$opt->{help},
|
||||
"V|version" => \$opt->{version}
|
||||
);
|
||||
|
||||
my $icinga1_cfg;
|
||||
my $icinga2_cfg = {};
|
||||
my $conf_prefix = "./conf";
|
||||
my $verbose = 0;
|
||||
our $dbg_lvl = 0;
|
||||
$icinga2_cfg->{'__I2EXPORT_DEBUG'} = 0;
|
||||
|
||||
if(defined($opt->{icinga1xcfg})) {
|
||||
$icinga1_cfg = $opt->{icinga1xcfg};
|
||||
}
|
||||
if(defined($opt->{icinga2xoutputprefix})) {
|
||||
$conf_prefix = $opt->{icinga2xoutputprefix};
|
||||
}
|
||||
if(defined($opt->{verbose})) {
|
||||
$verbose = $opt->{verbose};
|
||||
$icinga2_cfg->{'__I2EXPORT_DEBUG'} = 1;
|
||||
$dbg_lvl = 1;
|
||||
}
|
||||
|
||||
if (defined $opt->{version}) { print $version."\n"; exit 0; }
|
||||
if ($opt->{help}) { pod2usage(1); }
|
||||
|
||||
$icinga2_cfg->{'main'}= "$conf_prefix/icinga2.conf";
|
||||
$icinga2_cfg->{'resource'}= "$conf_prefix/resource.conf";
|
||||
$icinga2_cfg->{'hosts'}= "$conf_prefix/hosts.conf";
|
||||
$icinga2_cfg->{'services'}= "$conf_prefix/services.conf";
|
||||
$icinga2_cfg->{'users'}= "$conf_prefix/users.conf";
|
||||
$icinga2_cfg->{'groups'}= "$conf_prefix/groups.conf";
|
||||
$icinga2_cfg->{'notifications'}= "$conf_prefix/notifications.conf";
|
||||
$icinga2_cfg->{'timeperiods'}= "$conf_prefix/timeperiods.conf";
|
||||
$icinga2_cfg->{'commands'}= "$conf_prefix/commands.conf";
|
||||
|
||||
$icinga2_cfg->{'itl'}->{'host-template'} = "";
|
||||
$icinga2_cfg->{'itl'}->{'service-template'} = "";
|
||||
$icinga2_cfg->{'itl'}->{'user-template'} = "";
|
||||
$icinga2_cfg->{'itl'}->{'notification-template'} = "";
|
||||
$icinga2_cfg->{'itl'}->{'timeperiod-template'} = "legacy-timeperiod";
|
||||
$icinga2_cfg->{'itl'}->{'checkcommand-template'} = "plugin-check-command";
|
||||
$icinga2_cfg->{'itl'}->{'notificationcommand-template'} = "plugin-notification-command";
|
||||
$icinga2_cfg->{'itl'}->{'eventcommand-template'} = "plugin-event-command";
|
||||
|
||||
if (defined($opt->{hosttmpl})) {
|
||||
$icinga2_cfg->{'customtmpl'}->{'host-template'} = $opt->{hosttmpl};
|
||||
print "Custom host template: '" . $icinga2_cfg->{'customtmpl'}->{'host-template'} . "'\n";
|
||||
}
|
||||
if (defined($opt->{servicetmpl})) {
|
||||
$icinga2_cfg->{'customtmpl'}->{'service-template'} = $opt->{servicetmpl};
|
||||
print "Custom service template: '" . $icinga2_cfg->{'customtmpl'}->{'service-template'} . "'\n";
|
||||
}
|
||||
if (defined($opt->{usertmpl})) {
|
||||
$icinga2_cfg->{'customtmpl'}->{'user-template'} = $opt->{usertmpl};
|
||||
print "Custom user template: '" . $icinga2_cfg->{'customtmpl'}->{'user-template'} . "'\n";
|
||||
}
|
||||
if (defined($opt->{notificationtmpl})) {
|
||||
$icinga2_cfg->{'customtmpl'}->{'notification-template'} = $opt->{notificationtmpl};
|
||||
print "Custom notification template: '" . $icinga2_cfg->{'customtmpl'}->{'notification-template'} . "'\n";
|
||||
}
|
||||
if (defined($opt->{timeperiodtmpl})) {
|
||||
$icinga2_cfg->{'customtmpl'}->{'timeperiod-template'} = $opt->{timeperiodtmpl};
|
||||
print "Custom timeperiod template: '" . $icinga2_cfg->{'customtmpl'}->{'timeperiod-template'} . "'\n";
|
||||
}
|
||||
if (defined($opt->{checkcommandtmpl})) {
|
||||
$icinga2_cfg->{'customtmpl'}->{'checkcommand-template'} = $opt->{checkcommandtmpl};
|
||||
print "Custom checkcommand template: '" . $icinga2_cfg->{'customtmpl'}->{'checkcommand-template'} . "'\n";
|
||||
}
|
||||
if (defined($opt->{notificationcommandtmpl})) {
|
||||
$icinga2_cfg->{'customtmpl'}->{'notificationcommand-template'} = $opt->{notificationcommandtmpl};
|
||||
print "Custom notificationcommand template: '" . $icinga2_cfg->{'customtmpl'}->{'notificationcommand-template'} . "'\n";
|
||||
}
|
||||
if (defined($opt->{eventcommandtmpl})) {
|
||||
$icinga2_cfg->{'customtmpl'}->{'eventcommand-template'} = $opt->{eventcommandtmpl};
|
||||
print "Custom eventcommand template: '" . $icinga2_cfg->{'customtmpl'}->{'eventcommand-template'} . "'\n";
|
||||
}
|
||||
|
||||
|
||||
|
||||
my $type_cnt;
|
||||
|
||||
################################################################################
|
||||
# MAIN
|
||||
################################################################################
|
||||
|
||||
# TODO import/export files in parallel?
|
||||
|
||||
# verify that we have something to read
|
||||
if ( !-f $icinga1_cfg) {
|
||||
pod2usage(1);
|
||||
}
|
||||
|
||||
# the import
|
||||
my $icinga1_cfg_obj = Icinga2::ImportIcinga1Cfg::parse_icinga1_objects($icinga1_cfg);
|
||||
my $icinga1_cfg_obj_cache = Icinga2::ImportIcinga1Cfg::parse_icinga1_objects_cache($icinga1_cfg);
|
||||
my $icinga1_global_macros = Icinga2::ImportIcinga1Cfg::parse_icinga1_global_macros($icinga1_cfg);
|
||||
|
||||
# the conversion magic inside
|
||||
my $icinga2_cfg_obj = Icinga2::Convert::convert_2x($icinga2_cfg, $icinga1_cfg_obj, $icinga1_cfg_obj_cache, $icinga1_global_macros);
|
||||
|
||||
# the export
|
||||
Icinga2::ExportIcinga2Cfg::dump_cfg_resource_2x($icinga2_cfg, $icinga1_global_macros);
|
||||
Icinga2::ExportIcinga2Cfg::dump_cfg_obj_2x($icinga2_cfg, $icinga2_cfg_obj);
|
||||
|
||||
# print stats
|
||||
print "######################################################################\n";
|
||||
print "# CONVERSION STATISTICS\n";
|
||||
print "######################################################################\n";
|
||||
|
||||
Icinga2::Utils::print_sorted_hash($icinga2_cfg_obj->{'__I2_CONVERT_STATS'});
|
||||
|
||||
# vi: sw=4 ts=4 expandtab :
|
|
@ -1,6 +0,0 @@
|
|||
#!/bin/bash
|
||||
|
||||
ICINGA2BIN="$HOME/i2/sbin/icinga2"
|
||||
ICINGA2CONF="./icinga2-conv.conf"
|
||||
|
||||
$ICINGA2BIN -c $ICINGA2CONF
|
|
@ -0,0 +1,5 @@
|
|||
## Process this file with automake to produce Makefile.in
|
||||
|
||||
sbin_SCRIPTS = icinga2-migrate-config
|
||||
|
||||
|
|
@ -39,13 +39,13 @@ All required templates will be inherited from Icinga2's Template Library (ITL).
|
|||
Regular expressions are not supported, also for the reason that this is optional in Icinga 1.x
|
||||
|
||||
RUN
|
||||
# ./icinga2_convert_v1_v2.pl -c /etc/icinga/icinga.cfg -o conf/
|
||||
# /usr/sbin/icinga2-migrate-config -c /etc/icinga/icinga.cfg -o conf/
|
||||
|
||||
HELP
|
||||
# ./icinga2_convert_v1_v2.pl -h
|
||||
# /usr/sbin/icinga2-migrate-config -h
|
||||
|
||||
VERBOSE
|
||||
# ./icinga2_convert_v1_v2.pl -v -c /etc/icinga/icinga.cfg -o conf/
|
||||
# /usr/sbin/icinga2-migrate-config -v -c /etc/icinga/icinga.cfg -o conf/
|
||||
|
||||
TEST
|
||||
There's a small icinga2 conversion test config available, including conf/ folder.
|
||||
|
@ -68,7 +68,7 @@ DEBUG
|
|||
Compile Icinga2 with --enable-debug=yes and start it with -x. Alternatively, define the
|
||||
ConsoleLogger Object and set severity to "debug".
|
||||
|
||||
local object ConsoleLogger "my-debug-log" {
|
||||
object ConsoleLogger "my-debug-log" {
|
||||
severity = "debug"
|
||||
}
|
||||
|
1800
tools/configconvert/Icinga2/Convert.pm → tools/migration/icinga2-migrate-config
Normal file → Executable file
1800
tools/configconvert/Icinga2/Convert.pm → tools/migration/icinga2-migrate-config
Normal file → Executable file
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue