stroke has asked for the wisdom of the Perl Monks concerning the following question:

Hi, this script queries the defined list of DNS servers and grabs the serial numbers for the listed zones. It then compares them against each other and logs if they match or not. It may not be pretty, but it works !

But, the bit I'm struggling with now is how best to do the serial number comparison if the number of DNS server in the list changes - that is if I add in more or remove DNS server IPs to the list, I don't have to manually go and add/remove the serial number references for the check - I want to make the serial compare "dynamic", based on the number of DNS servers.

I'm okay with just comparing all other serials to the first serial number, rather than comparing all possible combinations.

fyi - I'm writing all the results out to a file for reference, in addition to sending errors only to STDOUT. Thanks

#!/usr/bin/env perl use strict; use warnings; use Net::DNS; use 5.010; my @nameservers = qw(8.8.8.8 4.2.2.2); my @errors; open(my $resultsfh, '>', "results-serials.csv") or die "cannot open > results-serials.csv: $!"; print $resultsfh "Result,Zone"; foreach (@nameservers) { print $resultsfh ",Serial for: $_"; } print $resultsfh "\n"; while (<DATA>) { my $fqdn = $_; chomp $fqdn; my @serials; my $res = Net::DNS::Resolver->new; $res->tcp_timeout(2); $res->udp_timeout(2); foreach my $ns (@nameservers) { $res->nameservers($ns); my $reply = $res->query("$fqdn", "SOA"); if ($reply) { push(@serials, ($reply->answer)[0]->serial); } else { push(@serials, $res->errorstring); } } # Compare Serials no warnings 'numeric'; if ($serials[0] == $serials[1]) { say $resultsfh "MATCH,$fqdn,$serials[0],$serials[1]"; } else { say $resultsfh "MISMATCH,$fqdn,$serials[0],$serials[1]"; push @errors, "MISMATCH.$fqdn,$serials[0],$serials[1]"; } } if (@errors) { say "ERRORS:"; foreach (@errors) { say "$_"; } } __DATA__ google.com apple.com

Replies are listed 'Best First'.
Re: Compare variables when the number of them vary
by CountZero (Bishop) on May 03, 2015 at 17:25 UTC
    That's a job for the all function of List::MoreUtils!

    Replace your test by

    if ( all { $serials[0] eq $_ } @serials ) { ...

    PS: I replaced your == test by eq and then you can probably delete the no warnings 'numeric';

    CountZero

    A program should be light and agile, its subroutines connected like a string of pearls. The spirit and intent of the program should be retained throughout. There should be neither too little or too much, neither needless loops nor useless variables, neither lack of structure nor overwhelming rigidity." - The Tao of Programming, 4.1 - Geoffrey James

    My blog: Imperial Deltronics
Re: Compare variables when the number of them vary
by hippo (Archbishop) on May 03, 2015 at 17:28 UTC

    I expect that really the only test you want to perform on the list of SOAs for a single domain is whether or not they are all the same. If there are any differences then that should be treated as a problem.

    So, instead of your test being if ($serials[0] == $serials[1]) try instead finding how many unique values are in the list, eg.

    use List::MoreUtils qw/uniq/; if (scalar (uniq @serials) == 1) { say $resultsfh join (',', 'MATCH', $fqdn, @serials); } else { say $resultsfh join (',', 'MISMATCH', $fqdn, @serials); push @errors, join (',', 'MISMATCH', $fqdn, @serials); }
Re: Compare variables when the number of them vary
by stroke (Acolyte) on May 05, 2015 at 09:08 UTC

    Thanks you. List::MoreUtils worked a treat. I tried both suggestions and they did the job ! Thanks