Beefy Boxes and Bandwidth Generously Provided by pair Networks
No such thing as a small change
 
PerlMonks  

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

by brianjb (Novice)
on May 15, 2013 at 19:11 UTC ( #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.

Comment on Compare zone files in directory with what is listed in named.conf
Select or Download Code
Re: Compare zone files in directory with what is listed in named.conf
by NetWallah (Abbot) 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 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 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 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
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? | Other CB clients
Other Users?
Others wandering the Monastery: (5)
As of 2014-09-21 16:59 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    How do you remember the number of days in each month?











    Results (172 votes), past polls