916623 - migrate_all_offline.sh fails on duplicity
1) We should skip all hosts, which are already inserted into the database,
hostname is the primary key there.
2) When a service in /etc/services has different port for TCP and UPD,
we must use different dn: for them - let's add '+udp' and '+tcp' prefix
to them
3) LDAP is case insensitive, while /etc/services is case sensitive.
Therefore skip all services, which would clash in LDAP.
diff -up MigrationTools-47/migrate_hosts.pl.orig MigrationTools-47/migrate_hosts.pl
--- MigrationTools-47/migrate_hosts.pl.orig 2013-08-08 11:33:36.098638903 +0200
+++ MigrationTools-47/migrate_hosts.pl 2013-08-08 11:33:47.250619710 +0200
@@ -51,34 +53,56 @@ while(<INFILE>)
next if /^#/;
s/#(.*)$//;
local($hostaddr, $hostname, @aliases) = split(/\s+/);
-
- if ($use_stdout) {
- &dump_host(STDOUT, $hostaddr, $hostname, @aliases);
- } else {
- &dump_host(OUTFILE, $hostaddr, $hostname, @aliases);
- }
+ &add_host($hostaddr, $hostname, @aliases)
}
+if ($use_stdout) {
+ &dump_hosts(STDOUT);
+} else {
+ &dump_hosts(OUTFILE);
+}
+
+# hash hostname -> IPaddresses
+%hosts={};
-sub dump_host
+sub add_host
{
- local($HANDLE, $hostaddr, $hostname, @aliases) = @_;
- local($dn);
+ local($hostaddr, $hostname, @aliases) = @_;
return if (!$hostaddr);
+
+ if ($hosts{$hostname}) {
+ @addrs = @{$hosts{$hostname}};
+ push(@addrs, $hostaddr);
+ $hosts{$hostname} = [@addrs];
+ } else {
+ $hosts{$hostname} = [$hostaddr];
+ }
- print $HANDLE "dn: cn=$hostname,$NAMINGCONTEXT\n";
- print $HANDLE "objectClass: top\n";
- print $HANDLE "objectClass: ipHost\n";
- print $HANDLE "objectClass: device\n";
- print $HANDLE "ipHostNumber: $hostaddr\n";
- print $HANDLE "cn: $hostname\n";
- @aliases = uniq($hostname, @aliases);
- foreach $_ (@aliases) {
- if ($_ ne $hostname) {
- print $HANDLE "cn: $_\n";
+ foreach (@aliases) {
+ if ($hosts{$_}) {
+ @addrs = @{$hosts{$_}};
+ push(@addrs, $hostaddr);
+ } else {
+ @hosts{$_} = [$hostaddr];
+ }
+ }
+}
+
+sub dump_hosts
+{
+ my $HANDLE = shift;
+ for my $hostname ( keys %hosts ) {
+ print $HANDLE "dn: cn=$hostname,$NAMINGCONTEXT\n";
+ print $HANDLE "cn: $hostname\n";
+ print $HANDLE "objectClass: top\n";
+ print $HANDLE "objectClass: ipHost\n";
+ print $HANDLE "objectClass: device\n";
+ @addrs = @{$hosts{$hostname}};
+ for my $hostaddr (@addrs) {
+ print $HANDLE "ipHostNumber: $hostaddr\n";
}
+ print $HANDLE "\n";
}
- print $HANDLE "\n";
}
close(INFILE);
diff -up MigrationTools-47/migrate_services.pl.orig MigrationTools-47/migrate_services.pl
--- MigrationTools-47/migrate_services.pl.orig 2013-08-08 13:14:48.404960042 +0200
+++ MigrationTools-47/migrate_services.pl 2013-08-08 13:14:26.000000000 +0200
@@ -186,6 +187,17 @@ sub build_service_records
$suffix = "+ipServicePort=" . &escape_metacharacters($port);
}
+ # Add suffix also when UDP and TCP port differ, but the service name is the same
+ if (exists $Rh_portmap->{$servicename}{"udp"}
+ and exists $Rh_portmap->{$servicename}{"tcp"}) {
+ my @udpport = keys(%{$Rh_portmap->{$servicename}{'udp'}});
+ my @tcpport = keys(%{$Rh_portmap->{$servicename}{'tcp'}});
+
+ if (!(@udpport ~~ @tcpport)) {
+ $suffix = "-" . $proto;
+ }
+ }
+
# Normalize aliases across protocols. Yet
# another uncomfortable compromise.
foreach (keys %{$Rh_services->{$port}{$servicename}{$proto}{'aliases'}}) {
diff -up MigrationTools-47/migrate_services.pl.orig MigrationTools-47/migrate_services.pl
--- MigrationTools-47/migrate_services.pl.orig 2013-08-08 13:21:16.191273547 +0200
+++ MigrationTools-47/migrate_services.pl 2013-08-08 13:42:14.497330286 +0200
@@ -93,6 +93,8 @@ sub parse_services
my %protocols_found = ();
my $card = '';
+ my %loservices = (); # lower-case service names
+ my %services = (); # service names
readloop:
while(defined($card = <INFILE>))
{
@@ -104,10 +106,15 @@ sub parse_services
# do not generate ddp services - it's AppleTalk, not IP
if ($proto eq "ddp") {
- print STDERR "Skipping non-IP service '$servicename $portproto'\n";
+ print STDERR "Skipping non-IP service '$servicename $portproto'.\n";
next;
}
-
+ if (exists $loservices{lc($servicename)} and !exists $services{$servicename}) {
+ print STDERR "Skipping service '$servicename', it clashes with services '".$loservices{lc($servicename)}."' because LDAP is case-insensitive.\n";
+ next;
+ }
+ $services{$servicename} = $servicename;
+ $loservices{lc($servicename)} = $servicename;
# Find services specifying a port range (e.g. X11.)
my $loport = '';
my $hiport = '';