e-smith-hosts/root/etc/e-smith/events/actions/conf-migrate-hosts

273 lines
7.9 KiB
Perl

#!/usr/bin/perl -w
#----------------------------------------------------------------------
# copyright (C) 2002-2005 Mitel Networks Corporation
#
# 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#
#----------------------------------------------------------------------
#--------------------------------------------------
# Names in the hosts database can be:
# - Internal name only (name for host on local LAN)
# hp4500=host|InternalIP|192.168.16.201|MacAddress|aa:bb:cc:dd:ee:ff
#
# - Hosted by e-smith server (internal/external on e-smith server)
# mail=host|ExternalIP|self|InternalIP|self
#
# - Externally hosted
# www=host|ExternalIP|a.b.c.d
#
# - Internal machine behind port-forwarding firewall
# secure=host|ExternalIP|d.e.f.g|InternalIP|w.x.y.z
#
# Unqualified names in the key apply to all domains
# FQDNs apply to specific domains and override the wildcard shortnames
#--------------------------------------------------
package esmith;
use strict;
use Errno;
use esmith::HostsDB;
my $hdb = esmith::HostsDB->open();
=begin testing
use esmith::TestUtils qw(scratch_copy);
my $h_tmp = '50-hosts/hosts.conf.4.1.2';
my $c_scratch = scratch_copy('50-hosts/configuration.conf');
$ENV{ESMITH_HOSTS_DB} = $h_tmp;
$ENV{ESMITH_CONFIG_DB} = $c_scratch;
# 4.1.2 Hosts DB which caused bug 2495
open(TMP, ">$h_tmp") || die $!;
print TMP <<'OUT';
archie=host|ExternalIP|209.28.139.23|InternalIP|self
e-smith=host|ExternalIP|self|InternalIP|self
e-smith-manager=host|ExternalIP|self|InternalIP|self
ftp=host|ExternalIP|self|InternalIP|self
mail=host|ExternalIP|self|InternalIP|self
proxy=host|ExternalIP|self|InternalIP|self
server=host|ExternalIP|self|InternalIP|self
www=host|ExternalIP|self|InternalIP|202.49.164.27
OUT
close TMP;
END { unlink $h_tmp }
system($^X, $Original_File);
use esmith::ConfigDB;
use esmith::HostsDB;
my $migrated = esmith::HostsDB->open;
my $config = esmith::ConfigDB->open;
my $domain = $config->get('DomainName')->value;
my $www = $migrated->get("www.$domain");
isa_ok( $www, 'esmith::DB::Record' );
is( $www->prop('InternalIP'), '202.49.164.27' );
is( $www->prop('ExternalIP'), '' );
is( $www->prop('HostType'), 'Local' );
my $archie = $migrated->get("archie.$domain");
isa_ok( $archie, 'esmith::DB::Record' );
is( $archie->prop('InternalIP'), '', 'InternalIP');
is( $archie->prop('ExternalIP'), '209.28.139.23', 'ExternalIP' );
is( $archie->prop('HostType'), 'Remote', 'HostType' );
my @migrated = grep { $_->key !~ /^(archie|www)/ }
$migrated->get_all_by_prop(type => 'host');
is_deeply( [ sort map { $_->key } @migrated ],
[ sort map { "$_.$domain" }
qw( e-smith e-smith-manager ftp mail proxy server )],
'domain names fully qualified'
);
foreach my $host (@migrated) {
my $dn = $host->key;
is( $host->prop('HostType'), 'Self', "$dn - HostType");
is( $host->prop('ExternalIP'), '' , " ExternalIP" );
is( $host->prop('InternalIP'), '' , " InternalIP" );
}
=end testing
=cut
#------------------------------------------------------------
# Populate the hosts database with default entries if they
# they don't already exist
#------------------------------------------------------------
my $event = $ARGV [0];
#------------------------------------------------------------
# Migrate existing hosts to new format for primary domain, and
# for any existing virtual domains
#
# eg. www=host|... -> www.{$DomainName}=host|...
#------------------------------------------------------------
my @FQDNHostList = ();
my @ShortHostList = ();
foreach my $host ($hdb->hosts)
{
if ($host->key =~ /\./)
{
# keep track of fully qualified domain name hosts
push @FQDNHostList, $host->key;
}
else
{
# keep track of single word hosts
push @ShortHostList, $host->key;
}
}
# Get the list of local domain names
use esmith::DomainsDB;
my $ddb = esmith::DomainsDB->open_ro();
my @domainsList = map { $_-> key } $ddb->domains;
eval "require esmith::NetworkServicesDB";
unless ($@)
{
my $nsdb = esmith::NetworkServicesDB->open();
if ($nsdb)
{
my $service_domain = $nsdb->service_domain();
push @domainsList, $service_domain if $service_domain;
}
}
#-------------------------------------------------------
# Iterate over each domain to propagate the single host
# entries for each virtual domain
#-------------------------------------------------------
foreach my $domain ( @domainsList )
{
# default visibility property is 'Local' as this never existed before
my %properties = (
Visibility => 'Local'
);
foreach my $host ( @ShortHostList )
{
$properties{'InternalIP'} =
$hdb->get_prop ($host, 'InternalIP') || '';
$properties{'ExternalIP'} =
$hdb->get_prop ($host, 'ExternalIP') || '';
$properties{'MACAddress'} =
$hdb->get_prop ($host, 'MACAddress') || '';
my $FQDN = "$host.$domain";
next if (defined $hdb->get ($FQDN));
# If defined as host 'self', change to new format
if (($properties{'InternalIP'} eq 'self') &&
($properties{'ExternalIP'} eq 'self'))
{
$properties{'HostType'} = 'Self';
$properties{'InternalIP'} = '';
$properties{'ExternalIP'} = '';
$properties{'MACAddress'} = '';
}
# defined as 'local' entry in new format
elsif( $properties{InternalIP} ne 'self' )
{
$properties{'HostType'} = 'Local';
$properties{ExternalIP} = '';
}
elsif( $properties{ExternalIP} ne 'self' )
{
$properties{'HostType'} = 'Remote';
$properties{InternalIP} = '';
}
else {
warn "$host has no InternalIP or ExternalIP!\n";
}
$properties{'type'} = 'host';
$hdb->new_record($FQDN, \%properties);
}
}
#-------------------------------------------------------
# Iterate over all of the fully qualified domain names,
# setting valid ones (from @domainsList) with appropriate
# values and flagging other non-expected ones with errors
#-------------------------------------------------------
foreach my $key ( @FQDNHostList )
{
# Skip the hosts if already in the new format
next if (defined $hdb->get_prop ($key, 'HostType'));
my %properties = (
Visibility => 'Local'
);
my ($tempHost, $tempDomain) = split /\./, $key, 2;
my @matches = grep(/$tempDomain/, @domainsList);
unless (@matches)
{
# doesn't match an existing domain, set error flag
$properties{'error'} = 'Host has no matching domain in system';
}
$properties{'InternalIP'} = $hdb->get_prop ($key, 'InternalIP') || '';
$properties{'ExternalIP'} = $hdb->get_prop ($key, 'ExternalIP') || '';
$properties{'MACAddress'} = $hdb->get_prop ($key, 'MACAddress') || '';
# If defined as host 'self', change to new format
if ($properties{'InternalIP'} eq 'self')
{
$properties{'HostType'} = 'Self';
$properties{'InternalIP'} = '';
$properties{'ExternalIP'} = '';
$properties{'MACAddress'} = '';
}
else # defined as 'local' entry in new format
{
$properties{'HostType'} = 'Local';
$properties{'ExternalIP'} = '';
}
$properties{'type'} = 'host';
$hdb->new_record($key, \%properties);
}
# Remove the old single host entries
foreach my $host ( @ShortHostList )
{
$hdb->get($host)->delete;
}
exit (0);