1
0
mirror of https://github.com/StackExchange/dnscontrol.git synced 2024-05-11 05:55:12 +00:00

NEW: zone2dnscontrol: Convert zonefiles to DNSControl.

This commit is contained in:
Tom Limoncelli
2017-03-14 16:10:46 -07:00
parent 004d817349
commit dc1e9f7210
4 changed files with 212 additions and 0 deletions

View File

@ -0,0 +1,22 @@
# zone2dnscontrol -- Converts a standard DNS zonefile into a DNS zone.
This script helps convert an old-style DNS zone file into the
DNSControl language. It isn't perfect but it will do 99 percent
of the work so you can focus on just fine-tuning it.
You must give the script both the zone name (i.e. "stackoverflow.com")
and the filename of the zonefile to read.
Output is sent to stdout.
Example:
"""
./convert stackoverflow.com zone.stackoverflow.com
"""
Caveats:
* TTLs are stripped out and/or ignored.
* `$INCLUDE` may not be handled correctly if you are not in the right directory.
* `$GENERATE` is not handled at all.

View File

@ -0,0 +1,38 @@
BEGIN {
print ""
print "D('" domain ", FILL_IN_REGISTRAR, DnsProvider(FILL_IN_PROVIDER),"
}
END {
print "END)"
}
$3 == "SOA" || $4 == "SOA" {
next
}
$3 == "A" || $3 == "CNAME" || $3 == "NS" {
name = $1
if (name == domain".") { name = "@" }
print "\t" $3 "('" name "', '" $4 "')," ;
next
}
$3 == "MX" {
name = $1
if (name == domain".") { name = "@" }
print "\tMX('" name "', " $4 ", '" $5 "')," ;
next
}
$3 == "TXT" {
name = $1
if (name == domain".") { name = "@" }
$1 = "";
$2 = "";
$3 = "";
print "\tTXT('" name "', " $0 ")," ;
next
}
{ print "UNKNOWN:" $0 }

144
misc/zone2dnscontrol/canonzone Executable file
View File

@ -0,0 +1,144 @@
#!/usr/bin/perl
# Copyright 2005 Thomas A. Limoncelli
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
# canonzone [domain]
# Purpose: Cannonicalize a zone file so that dumber scripts can have
# an easier time parsing it.
# Input: A real zone file with many formatting nasties.
# Output: The zone file with one RR per line
# $ORIGIN's removed
# $TTL's removed
# $INCLUDE's replaced with the file's contents
# Lines that include TTL's have TTL's removed.
# Lines that begin with whitespace turning into regular RR's
# All hostnames turned into FQDN's (with exception listed below)
# If a FQDN ends with [domain], it is removed.
# Output in a strict format of:
# HOSTNAME.domain.<TABS>IN<SPACE>TYPE<TAB>DATA\n
# or for hosts in the [domain]:
# HOSTNAME<TABS>IN<SPACE>TYPE<TAB>DATA\n
#
# Defaults:
# If "domain" is left off the command line, we assume "bell-labs.com."
#
# TODO:
# Handle $GENERATE better. Include an option that expands the hosts.
#
if ($ARGV[0] =~ /-n/) {
shift @ARGV;
$nostripend = 1;
}
# our defaults
$origin = 'cibernet.com.';
$origin = shift @ARGV if defined($ARGV[0]);
$stripend = $origin; $stripend =~ s/(\.)/\\$1/g;
#print STDERR "; $origin $stripend\n";
die "ARGV[1] $stripend does not end in ." unless $stripend =~ /\.$/;
die "ARGV[1] $origin does not end in ." unless $origin =~ /\.$/;
# intialize things
$defname = '';
$host = '';
#$noprevioushost = 1;
&doit(STDIN);
sub doit {
local(*FILE) = @_;
while (<FILE>) {
# process whitespace, comments, and continuations:
chomp;
# the order of the next three lines is very important
s/;.*//; # toss comments
next if /^\s*$/; # skip blank lines
redo if ( /\(/ && ! /\)/ ) && ($_ .= <>); # handle continuations
# Handle the meta stuff:
if (/^\$ORIGIN\s+/) { # handle the $ORIGIN statements
($junk, $origin, @junk) = split;
# $noprevioushost = 1;
die "ORIGIN $origin does not end in ." unless $origin =~ /\.$/;
chomp;
next;
} elsif (/^\$GENERATE\s+/) { # handle the $GENERATE statement
s/\s+/ /g; # change whitespace to a single space
print; print "\n";
next;
} elsif (/^\$TTL\s+/) { # handle the $TTL statement
# do nothing
next;
} elsif (/^\$INCLUDE\s+/) { # handle the $INCLUDE statements
($junk, $filename, @junk) = split;
die "INCLUDE file doesn't exist" unless -f $filename;
print "; INCLUDE BEGIN $filename\n";
open(INCFILE, "<" . $filename) || die "Can not read $filename: $!";
&doit(INCFILE);
close INCFILE;
print "; INCLUDE END $filename\n";
next;
} elsif (/^\$/) {
die "ERROR1: I don't understand this \$ line: $_\n";
}
# ASSERTION at this point we know the line is just a RR.
# if the line begins with whitespace, prepend the last host.
# BUG: this may not handle "last host" across $INCLUDEs properly
if (/^\s/) { # line begins with whitespace
$_ = $defname . " " . $_;
}
# Extract the host, type, and data from the RR:
if (/(\S+)\s+(\d*)\s+IN\s+(\S+)\s+(.*)/i) { # host ttl IN rrtype data
($h, $junk, $TYPE, $data) = ($1, $2, $3, $4);
#print "read: HOST:$h JUNK:$junk TYPE:$TYPE DATA:$data\n";
} elsif (/(\S+)\s+IN\s+(\S+)\s+(.*)/i) { # host IN rrtype data
($h, $TYPE, $data) = ($1, $2, $3);
#print "read: HOST:$h TYPE:$TYPE DATA:$data\n";
} elsif (/(\S+)\s+(\S+)\s+(.*)/i) { # host IN rrtype data
($h, $TYPE, $data) = ($1, $2, $3);
#print "read: HOST:$h TYPE:$TYPE DATA:$data\n";
} else {
die "ERROR2: I don't understand this line:\n$_\n";
}
$h = $origin if $h eq '@'; # "@" is shorthand for the origin
# if the hostname is not a FQDN, append the $origin
if ( $h =~ /\.$/ ) {
$host = $h;
} else {
$host = $h . "." . $origin;
}
$defname = $host; # record what will be the next line's default hostname
# remove the domain we are stripping the zone:
$host =~ s/\.$stripend$//i unless $nostripend;
# Format and print the RR:
$TAB = ''; $TAB = "\t" if length($host) < 8;
print "${host}\t${TAB}IN ${TYPE}\t$data\n";
}
}

View File

@ -0,0 +1,8 @@
#! /usr/bin/env bash
if [[ $# != 2 ]]; then
echo "Usage: $0 zonename filename"
exit 1
fi
./canonzone $1"." <$2 | awk -v domain="$1" -f ./awkfile.awk