mirror of
https://github.com/Icinga/icinga2.git
synced 2025-07-30 17:14:25 +02:00
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/execvpe/Makefile
|
||||||
third-party/mmatch/Makefile
|
third-party/mmatch/Makefile
|
||||||
tools/Makefile
|
tools/Makefile
|
||||||
|
tools/migration/Makefile
|
||||||
tools/i2enfeature
|
tools/i2enfeature
|
||||||
tools/mkembedconfig/Makefile
|
tools/mkembedconfig/Makefile
|
||||||
])
|
])
|
||||||
|
@ -26,8 +26,7 @@ possible.
|
|||||||
> Please check the provided README file for additional notes and possible
|
> Please check the provided README file for additional notes and possible
|
||||||
> scaveats.
|
> scaveats.
|
||||||
|
|
||||||
# cd tools/configconvert
|
# /usr/sbin/icinga2-migrate-config -c /etc/icinga/icinga.cfg -o conf/
|
||||||
# ./icinga2_convert_v1_v2.pl -c /etc/icinga/icinga.cfg -o conf/
|
|
||||||
|
|
||||||
|
|
||||||
### Manual Config Conversion
|
### Manual Config Conversion
|
||||||
|
@ -215,6 +215,7 @@ fi
|
|||||||
%{_bindir}/%{name}
|
%{_bindir}/%{name}
|
||||||
%{_sbindir}/i2enfeature
|
%{_sbindir}/i2enfeature
|
||||||
%{_sbindir}/i2disfeature
|
%{_sbindir}/i2disfeature
|
||||||
|
%{_sbindir}/icinga2-migrate-config
|
||||||
%exclude %{_libdir}/%{name}/libdb_ido_mysql*
|
%exclude %{_libdir}/%{name}/libdb_ido_mysql*
|
||||||
%{_libdir}/%{name}
|
%{_libdir}/%{name}
|
||||||
%{_datadir}/doc/%{name}
|
%{_datadir}/doc/%{name}
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
SUBDIRS = \
|
SUBDIRS = \
|
||||||
|
migration \
|
||||||
mkembedconfig
|
mkembedconfig
|
||||||
|
|
||||||
sbin_SCRIPTS = i2enfeature
|
sbin_SCRIPTS = i2enfeature
|
||||||
|
@ -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
|
|
5
tools/migration/Makefile.am
Normal file
5
tools/migration/Makefile.am
Normal file
@ -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
|
Regular expressions are not supported, also for the reason that this is optional in Icinga 1.x
|
||||||
|
|
||||||
RUN
|
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
|
HELP
|
||||||
# ./icinga2_convert_v1_v2.pl -h
|
# /usr/sbin/icinga2-migrate-config -h
|
||||||
|
|
||||||
VERBOSE
|
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
|
TEST
|
||||||
There's a small icinga2 conversion test config available, including conf/ folder.
|
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
|
Compile Icinga2 with --enable-debug=yes and start it with -x. Alternatively, define the
|
||||||
ConsoleLogger Object and set severity to "debug".
|
ConsoleLogger Object and set severity to "debug".
|
||||||
|
|
||||||
local object ConsoleLogger "my-debug-log" {
|
object ConsoleLogger "my-debug-log" {
|
||||||
severity = "debug"
|
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…
x
Reference in New Issue
Block a user