Thursday, 22 March 2007

Mass-migrating websites - DNS changes tracking

First shot - migrate several hundreds of websites from one server to another... Copying is a simple task... creating config files is simple task... changing DNS records is boring (and simple)... but keeping track of which DNS domains were properly propagated and which not is a stupid and annoying job... Perl to the rescue!
This is based on several assumptions:
  • we use apache2-like way of configuration - all virtual hosts in separate files
  • each file has one ServerName statement and possibly ServerAlias with unlimited amount of names following it
  • each file has the same name as domain - either with or without 'www' at the beginning (so for sure it has at least one dot in the name)
  • we are only interested in the DNS records pointing to the right IP



I rolled out a simple perl script that does it for me. As most of the domains I manage have TTL between 20 minutes and 3 hours I run it several times a day and just check the list of domains that were transferred or not...

#!/usr/bin/perl
use strict;

my @files=glob ("*.*");
my %checks;
my $k;
my $expected_IP = '11.22.33.44';

foreach my $k (@files) {
  open (FH, $k);
  while(<FH>) {
    chomp;
    if (/Server(Name|Alias)s+(.*?)$/i) {
      $checks{$k} .= "$2 ";
    }
  }
}

my (%OK, %NOK);

foreach my $k (sort keys %checks) {
  my @t = split(/s+/, $checks{$k});
  print "Testing file $kn";
  foreach my $h (sort @t) {
    next if length($h) < 5;
    my $r = `host -t A $h`;
    if ($r =~ /SERVFAIL/) {
      print "  - $h (domain NOT REGISTERED)n";
    } elsif ($r =~ /NXDOMAIN/) {
      print "  - $h (domain exists but HOST UNKNOWN)n";
    } elsif (length($r) < length($h)) {
      print "  - $h (query returned NO DATA at all)n";
    } else {
      $r =~ m/s+(d{1,3}.d{1,3}.d{1,3}.d{1,3})$/;
      $1 eq $expected_IP ? print "  + $hn" : print "  - $h ($1)n";
    }
  }
}

As a result I get a list like (domain names are fake of course):

Testing file test.domain.com
  + test.domain.com (11.22.33.44)
  - www.test.domain.com (domain exists but HOST UNKNOWN)
Testing file wp.pl
  - wp.pl (212.77.100.101)
  - www.wp.pl (212.77.100.101)

... as a finishing touch - cron it, pipe it to email...

heck-DNS.pl | mail lazy-admin@somewhere.com -t "DNS domains maps on `date`"

Have fun!