Beefy Boxes and Bandwidth Generously Provided by pair Networks
There's more than one way to do things
 
PerlMonks  

Compare zone files in directory with what is listed in named.conf

by brianjb (Novice)
on May 15, 2013 at 19:11 UTC ( [id://1033730]=perlquestion: print w/replies, xml ) Need Help??

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

I would really appreciate any assistance that I can get here. I am fairly new to perl. I am trying to rewrite my shell scripts to perl. Currently I have a shell script (using sed, awk, grep, etc) that gets a list of all of the zone files in a directory and then looks in named.conf for what is expected to be in there. If there is a file in the directory that isn't listed in named.conf, then it emails and lets me know that there is some stale files for me to look at. In the past, I have used Text::Diff module to do a diff. Is there any way to put these into two arrays and do a diff without that module? Looking for feedback on either using a module, or doing it without a module. There is more than one way, right?

This is sample named.conf:

########################################### # BIND 9 name server configuration file ########################################### controls { inet 127.0.0.1 allow { localhost; } keys { "rndc-key"; }; }; zone "test.com" in { type master; file "db.test.com"; notify yes; }; zone "brian.com" in { type master; file "db.brian.com"; notify yes; }; zone "." in { type hint; file "db.cache"; }; zone "0.0.127.in-addr.arpa" in { type master; file "db.127.0.0"; };

This is listing of zonefiles in directory:

computer:zonefiles brian$ ls -al ~/zonefiles total 0 drwxr-xr-x 5 brian brian 170 May 15 14:58 . drwxr-xr-x 11 brian brian 374 May 15 14:59 .. -rw-r--r-- 1 brian brian 0 May 15 14:48 db.127.0.0 -rw-r--r-- 1 brian brian 0 May 15 14:48 db.brian.com -rw-r--r-- 1 brian brian 0 May 15 14:48 db.test.com

This is the script so far:

#!/usr/bin/perl # Putting all of the zonefiles lised in named.conf into an array my $srce = "named.conf.brian"; my $string1 = "db."; open(my $FH, $srce) or die "Failed to open file $srce ($!)"; my @buf = <$FH>; close($FH); my @lines = grep (/$string1/, @buf); #grepping for db. map {s/"//g; } @lines; #removing quotation marks map {s/;//g; } @lines; #removing semicolon #map {s/^.*file.*db.//g; } @lines; #removing file db. map {s/^.*file //g; } @lines; #removing the word file print @lines; # Putting listing of all of the files in ~/zonefiles directory into a +n array # Assigning variable to directory my $directory = "~/zonefiles/"; opendir(D, "$directory") || die "Can't opendir $directory: $!\n"; my @list = readdir(D); closedir(D); foreach my $f (@list) { print "$f\n"; }

This is the output when I run it:

computer:tmp brian$ ./brian.pl db.test.com db.brian.com db.cache db.127.0.0 . .. 9 db.127.0.0 db.brian.com db.test.com

How would I ignore things that I don't want to check? For example, ignore db.cache in named.conf. I also want to ignore "." and ".." in the zone file directory.

Replies are listed 'Best First'.
Re: Compare zone files in directory with what is listed in named.conf
by NetWallah (Canon) on May 15, 2013 at 20:06 UTC
    Untested, but this should meet your requirements:
    #!/usr/bin/perl # Putting all of the zonefiles lised in named.conf into an array use strict; use warnings; my $srce = "named.conf.brian"; my %zonefilenames; open(my $FH, "<", $srce) or die "Failed to open file $srce ($!)"; while (<$FH>){ next unless my ($filename) = m/file\s*"([^"]+)/; next if $filename eq "db.cache"; $zonefilenames{ $filename } =""; } close($FH); print "Zone Files: ",join( ", ", keys %zonefilenames)," \n"; # Putting listing of all of the files in ~/zonefiles directory into a +n array # Assigning variable to directory my $directory = "~/zonefiles/"; opendir(my $D, "$directory") or die "Can't opendir $directory: $!\n"; while ( readdir($D)){ next if m/^\./; # Ignore things with leading dots chomp; my $found = exists $zonefilenames{ $_ } ? "" : "Not found in zone +definition"; print "$_ : $found\n"; } closedir($D);
    Update : Enabled "strict" and fixed code typos.

                 "I'm fairly sure if they took porn off the Internet, there'd only be one website left, and it'd be called 'Bring Back the Porn!'"
            -- Dr. Cox, Scrubs

Re: Compare zone files in directory with what is listed in named.conf
by ig (Vicar) on May 15, 2013 at 20:27 UTC

    Yet another way..

    use strict; use warnings; # Putting all of the zonefiles lised in named.conf into an array my $srce = "named.conf.brian"; open(my $FH, $srce) or die "Failed to open file $srce ($!)"; my @files = map { /"([^"]*)/; # get the filename $1 } grep { /^\s*file / } <$FH>; close($FH); # Putting listing of all of the files in ~/zonefiles directory into a +n array # Assigning variable to directory my $directory = "~/zonefiles"; opendir(D, "$directory") || die "Can't opendir $directory: $!\n"; my @list = grep { $_ !~ m/^(\.|\.\.)$/ } readdir(D); closedir(D); # Make hashes of the lists my %configured = map { $_ => 1 } @files; my %existing = map { $_ => 1 } @list; print "Missing zone files:\n"; foreach my $file (@files) { next if($existing{$file}); print "\t$file\n"; } print "Unconfigured zone files:\n"; foreach my $file (@list) { next if($configured{$file}); print "\t$file\n"; }
Re: Compare zone files in directory with what is listed in named.conf
by fisher (Priest) on May 15, 2013 at 20:15 UTC
    Just skip it.
    open F, "named.conf.local" or die "$!"; while(<F>) { chomp; s/^[ \t]*file "db\.(.*)";/$1/ or next; next if /db.cache/; push @lines, $_; } close F;
    and
    opendir D, "$directory" || die "Cant: $1"; my @list = grep /db/, readdir(D); closedir D;
Re: Compare zone files in directory with what is listed in named.conf
by Kenosis (Priest) on May 15, 2013 at 22:17 UTC

    The following first captures the file names in named.conf and places them into a hash. It then globs the zonefiles' directory, and attempts to find each listed file from that directory in the hash. If the file name's not in the hash, it's pushed onto @unlistedFiles for later processing:

    use strict; use warnings; my ( %named_conf, @unlistedFiles ); open my $fh, '<', 'named.conf' or die $!; /\s+file\s+"([^"]+)/ and $named_conf{$1}++ for <$fh>; close $fh; chdir 'zonefiles' or die $!; !defined $named_conf{$_} and push @unlistedFiles, $_ for <db.*>; print "$_\n" for @unlistedFiles;

    Files in zonefiles directory:

    db.127.0.0 db.brian.com db.cache db.test.com db.what db.why

    Output using your named.conf:

    db.what db.why

    Hope this helps!

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://1033730]
Approved by fisher
Front-paged by fisher
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others chanting in the Monastery: (3)
As of 2024-04-25 06:50 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found