View Full Version : Increment number of a dns zone
clinty
March 6th, 2009, 15:43
Hello.
I'm looking for a solution to add a subdomain to a domain zone. The 'problem' is for increment zone number.
If it does not contains the date of today, I replace it by yyyymmdd01. This case is easy.
However, if it contains the date of today, I must replace by the same date, and increment the two last numbers. If number was 2009030603, I must replace by 2009030604.
Any ideas for this case? What tools must I use?
Thanks!
DutchDaemon
March 6th, 2009, 16:02
A shell script with grep, awk, cut, sed, expr. Or a perl script. I'm sure there are scripts on the net for something this common.
DutchDaemon
March 6th, 2009, 17:07
Sometimes I indulge in filthy dirty shell script hacks .. ;)
Call it 'cereal' and call the zonefile as (e.g.)
cereal db.testnet.net
#!/bin/sh
# Copyright: whatever!
# Don't bug DutchDaemon!
# read zonefile from cmd
zone=$1
# get serial number
serial=$(grep 'serial no' $zone | awk '{print $1}')
# get serial number's date
serialdate=$(echo $serial | cut -b 1-8)
# get today's date in same style
date=$(date +%Y%m%d)
# compare date and serial date
if [ $serialdate = $date ]
then
# if equal, just add 1
newserial=$(expr $serial + 1)
else
# if not equal, make a new one and add 00
newserial=$(echo $date"00")
fi
# edit zonefile in place, leaving a backup (.bak)
# experiment with amount of tabs (whitespace) needed to line up correctly
sed -i .bak "s/.*serial no.*/ $newserial ; serial no./" $zone
# show diffs
diff $zone $zone.bak
# bump zone
/usr/sbin/rndc reload $zone
exit 0
Test with old serial:
# cereal db.testnet.net
4c4
< 2009030600 ; serial no.
---
> 2009022300 ; serial no.
Test with a serial of today:
# cereal db.testnet.net
4c4
< 2009030601 ; serial no.
---
> 2009030600 ; serial no.
No guarantee, no beauty ;)
clinty
March 6th, 2009, 17:34
Sometimes I indulge in filthy dirty shell script hacks .. ;)
Call it 'cereal' and call the zonefile as (e.g.)
cereal db.testnet.net
#!/bin/sh
# Copyright: whatever!
# Don't bug DutchDaemon!
# read zonefile from cmd
zone=$1
# get serial number
serial=$(grep 'serial no' $zone | awk '{print $1}')
# get serial number's date
serialdate=$(echo $serial | cut -b 1-8)
# get today's date in same style
date=$(date +%Y%m%d)
# compare date and serial date
if [ $serialdate = $date ]
then
# if equal, just add 1
newserial=$(expr $serial + 1)
else
# if not equal, make a new one and add 00
newserial=$(echo $date"00")
fi
# edit zonefile in place, leaving a backup (.bak)
# experiment with amount of tabs (whitespace) needed to line up correctly
sed -i .bak "s/.*serial no.*/ $newserial ; serial no./" $zone
# show diffs
diff $zone $zone.bak
# bump zone
/usr/sbin/rndc reload $zone
exit 0
Test with old serial:
# cereal db.testnet.net
4c4
< 2009030600 ; serial no.
---
> 2009022300 ; serial no.
Test with a serial of today:
# cereal db.testnet.net
4c4
< 2009030601 ; serial no.
---
> 2009030600 ; serial no.
No guarantee, no beauty ;)
Wa... Great thank you!
I didn't test it yet, but I read it. Just a point:
# get serial number
serial=$(grep 'serial no' $zone | awk '{print $1}')
You take the serial by grep a 'serial no' string. This method depends on comments, so if we write 'Serial number', it won't work. Indeed, I do not write any comments in my master zone ;)
DutchDaemon
March 6th, 2009, 17:43
Sure, you'll have to adapt it to the way you do things, though the '; serial no.' comment in zonefiles is pretty stock BIND syntax. As long as you have a unique string to "grep on to" it should be easy.
clinty
March 6th, 2009, 18:09
# get serial number
serial=$(grep 'serial no' $zone | awk '{print $1}')
I think this grep is better... On this script, it's better to grep the serial no than a string/comment.
grep -e '2[0-9]\{9\} ${zone}
DutchDaemon
March 6th, 2009, 18:14
That should work for another 991 years, yes. It works for the sed part as well. Well, only if you use date-related serial numbers, of course. There are a lot of people using Unix seconds as a serial instead of a date.
clinty
March 6th, 2009, 18:20
No, that should work for 2xxx years. There's a '2'. I don't have 1xxx years, or 3xxx years. I believe...
--------
DutchDaemon:
It should work for years starting with a 2, so until the year 3000[010100]. Which is, i believe, about 991 years away.
(oops, sorry, edited your post instead of replying to it -- well, it's clear what we mean ...)
clinty
March 10th, 2009, 11:02
I copy you a version modified for my needs.
# vars
ZONEPATH=/etc/namedb/master
# check args
if [ ! $# -eq 1 ]; then
echo "Usage $0 domain.tld"
exit 1
fi
# read zonefile from cmd
ZONE=${ZONEPATH}/${1}
# check the file
if [ ! -f ${ZONE} ]; then
echo "Error: zone does not exist"
exit 1
fi
# get serial number
SERIAL=$(grep -e "2[0-9]\{3\}[0-1]\{1\}[0-9]\{1\}[0-3]\{1\}[0-9]\{1\}[0-9]\{2\}" ${ZONE} | awk '{print $1}')
# get serial number's date and number
SERIAL_DATE=$(echo ${SERIAL} | cut -b 1-8)
SERIAL_NUMBER=$(echo ${SERIAL} | cut -b 9-10)
# get today's date in same style
DATE_TODAY=$(date +%Y%m%d)
# compare date and serial date
if [ "${SERIAL_DATE}" = "${DATE_TODAY}" ]
then
# if equal, just add 1
# if equal and number equal 99, do not change
if [ ${SERIAL_NUMBER} -ge 99 ]; then
NEWSERIAL=${SERIAL}
else
# increment serial number
NEWSERIAL_NUMBER=$(expr $SERIAL_NUMBER + 1)
# if < 10, add a 0 to have 2 digits
if [ ${NEWSERIAL_NUMBER} -le 9 ]; then
NEWSERIAL_NUMBER="0"${NEWSERIAL_NUMBER}
fi
# construct new serial
NEWSERIAL=${SERIAL_DATE}${NEWSERIAL_NUMBER}
fi
else
# if not equal, make a new one and add 00
NEWSERIAL=$(echo ${DATE_TODAY}"01")
fi
# write the new serial
/usr/bin/sed -i -e "s/${SERIAL}/${NEWSERIAL}/g" ${ZONE}
#ok
exit 0
If you have advices or comments... ;)
DutchDaemon
March 10th, 2009, 12:07
Looks fine. Small glitch:
# if not equal, make a new one and add 00
NEWSERIAL=$(echo ${DATE_TODAY}"01")
vivek
March 16th, 2009, 19:31
I've something as follows:
#!/usr/local/bin/bash
ZROOT=/etc/named/zones/e
ZFILE=$ZROOT/zone.$1
S=$(grep Serial | awk '{ print $1}' ${ZFILE} )
N=$(( S++ ))
sed -i -e "s/${S}/${N}/g" ${ZFILE}
My serial is in following format:
2009012202
vBulletin® v3.8.7, Copyright ©2000-2012, vBulletin Solutions, Inc.