Skip to content

Instantly share code, notes, and snippets.

@sasha1sum
Created January 3, 2017 21:17
Show Gist options
  • Save sasha1sum/0d1cbfbd22c7348b8d1575754a3bad58 to your computer and use it in GitHub Desktop.
Save sasha1sum/0d1cbfbd22c7348b8d1575754a3bad58 to your computer and use it in GitHub Desktop.
#!/bin/bash
# A script to scrape a cloudformation for route53 resources and test them
CAT=`which cat`
DIFF=`which diff`
DIG=`which dig`
NAMESERVER1=""
NAMESERVER2=""
TEMPLATE=""
OUTPUT=0
TMPOUT1="/tmp/$(basename $0)-${RANDOM}"
TMPOUT2="/tmp/$(basename $0)-${RANDOM}"
VERBOSITY=0
#### Basic helpers
function show_help {
cat <<EOF
USAGE: $0 [OPTIONS] cloudformation.yml <nameserver1> <nameserver2>
Scrapes a cloudformation document for Route53 urls and runs a dig against them
* cloudformation.yml: yml definition of resource records to test, will run
against computers default dns servers
* If one nameserver is provided, it will run all queries against that server
* If two nameservers are provided, the result will be a diff between the two
OPTIONS:
-h,-? This message
-v Verbosity level
-t <tool> cat/diff tool to use
-o <path> output file path (will be named with .1 and .2 if needed)
EOF
}
function error {
echo "ERROR: $1" >&2
show_help >&2
exit 1
}
function warning {
echo WARNING: $@ >&2
}
function info {
[ $VERBOSITY -ge 1 ] && echo INFO: $@ >&2
}
function debug {
[ $VERBOSITY -ge 2 ] && echo DEBUG: $@ >&2
}
#### Dig functions
## replacement dig function which trims a lot of garbage and results
function dig {
args="-t ANY"
debug $DIG $args $@
$DIG $args +noall +answer $@ | sed "/^;/d" | sed "/^ *$/d" | awk '!($2="")' | sort
}
# HACK: reads in the cloudformaiont and assumes a DNS entry is anything
# which matches 'Name: "example.com."' (ie string ending in period)
function scrape_urls {
space=" *"
quote="[\"']\{0,1\}"
cat $1 |
sed "/Name:.*\.${quote}${space}/!d" |
sed "s/^${space}Name:${space}${quote}\(.*\)\.${quote}${space}$/\1/" |
sort |
uniq
}
#### Main
## Parse options
# Reset in case getopts has been used previously in the shell.
OPTIND=1
while getopts "h?vt:o:" opt; do
case "$opt" in
h|\?)
show_help
exit 0
;;
t) DIFF=${OPTARG}
CAT=${OPTARG}
;;
o) OUTPUT=1
TMPOUT1=${OPTARG}
;;
v) VERBOSITY=$((VERBOSITY+1))
;;
esac
done
shift $((OPTIND-1))
[ "$1" == "--" ] && shift
# test for template
TEMPLATE=$1
[ -z "$TEMPLATE" ] && error "template cannot be blank"
[ ! -f "$TEMPLATE" ] && error "template file does not exist"
shift
# Nameservers
[ $# -gt 2 ] && error "to many nameservers are provided, only use 0-2"
[ -n "$1" ] && NAMESERVER1=$1
[ -n "$2" ] && NAMESERVER2=$2
[ -n "$NAMESERVER2" ] && TMPOUT2="${TMPOUT1}__${NAMESERVER2}"
[ -n "$NAMESERVER1" ] && TMPOUT1="${TMPOUT1}__${NAMESERVER1}"
## Run
# quit if dig does not exist
[ -z "$DIG" ] && error "could not find dig on this machine"
# cleanup existing output
[ -e "$TMPOUT1" ] && rm -f $TMPOUT1
[ -e "$TMPOUT2" ] && rm -f $TMPOUT2
scrape_urls $TEMPLATE | while read url; do
info checking $url...
echo "## URL: $url" | tee -a $TMPOUT1 >> $TMPOUT2
# if no nameservers are provided, just run
if [ -z "$NAMESERVER1" ] && [ -z "$NAMESERVER2" ]; then
dig $url >> $TMPOUT1 2>&2
fi
# run against first nameserver
if [ -n "$NAMESERVER1" ]; then
dig "@$NAMESERVER1" $url >> $TMPOUT1 2>&2
fi
# run against second nameserver
if [ -n "$NAMESERVER2" ]; then
dig "@$NAMESERVER2" $url >> $TMPOUT2 2>&2
fi
echo "" | tee -a $TMPOUT1 >> $TMPOUT2
done
# if there is no second nameserver, just print output, otherwise diff
if [ -z "$NAMESERVER2" ]; then
$CAT $TMPOUT1
else
$DIFF $TMPOUT1 $TMPOUT2
fi
# cleanup tmpfiles if they were not manually set
if [ $OUTPUT -eq 0 ]; then
rm -f $TMPOUT1
rm -f $TMPOUT2
fi
@sasha1sum
Copy link
Author

Sometimes you start doing something in BASH for the simplicity and have regrets by the time you are done

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment