Skip to content

Instantly share code, notes, and snippets.

@hamsolodev
Created July 2, 2013 06:29
Show Gist options
  • Save hamsolodev/5907154 to your computer and use it in GitHub Desktop.
Save hamsolodev/5907154 to your computer and use it in GitHub Desktop.
#!/usr/bin/env python
# -*- coding: utf-8 -*-
#
# Update Route53 DNS A name record for home IP.
#
# Uses the *route53* library, rather than boto.
import os
import re
import sys
import requests
import route53
import route53.exceptions
## TODO print errors to stderr before exiting.
try:
TARGET_RRSET_NAME = os.environ['TARGET_RRSET_NAME']
AWS_ACCESS_KEY_ID = os.environ['AWS_ACCESS_KEY_ID']
AWS_SECRET_ACCESS_KEY = os.environ['AWS_SECRET_ACCESS_KEY']
except KeyError:
print('Set TARGET_RRSET_NAME, AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY')
sys.exit(1)
HOSTED_ZONE = '.'.join(TARGET_RRSET_NAME.split('.')[1:])
if not HOSTED_ZONE.endswith('.'):
print('TARGET_RRSET_NAME should be of the form host.domain.com.')
sys.exit(1)
def scrape_home_ip():
"""Get IP out of ADSL modem's admin pages.
Dumb as bag of spanners.
"""
req = requests.get('http://192.168.1.1/Status_Router.asp',
auth=('admin', 'admin'))
if req.status_code != 200:
print('Fucking router returned {}!'.format(req.status_code))
sys.exit(1)
try:
ip_addr = re.search(
r'.*netconn\.ipaddr.*?(?P<home_ip>\d+\.\d+\.\d+\.\d+)',
req.content,
flags=re.M|re.S).group('home_ip')
except AttributeError:
print(u'IP couldn\'t be scraped…')
sys.exit(1)
return ip_addr
def main(home_ip):
"""Retrieve external IP from home ADSL router then compare it with
a DNS record and, if they do not match, update the DNS record (via
AWS Route53) so they match.
"""
try:
conn = route53.connect(
aws_access_key_id=AWS_ACCESS_KEY_ID,
aws_secret_access_key=AWS_SECRET_ACCESS_KEY)
try:
# list zones, and pull out the one we're interested in
zone = [zone
for zone in conn.list_hosted_zones()
if zone.name == HOSTED_ZONE][0]
except IndexError:
print('No such Hosted Zone {}'.format(HOSTED_ZONE))
sys.exit(1)
try:
# get and save changes to an existing RR set…
rr_set = [rr_set
for rr_set in zone.record_sets
if rr_set.name == TARGET_RRSET_NAME \
and rr_set.rrset_type == 'A'][0]
# FIXME can rr_set.values ever be an empty list?!
if rr_set.records[0] == home_ip:
# IP hasn't changed, exit quietly
sys.exit()
else:
# update the record!
rr_set.records = [home_ip]
rr_set.save()
except IndexError:
# create a new RR set. note this will fail if a RRSet of
# the same name but different type exists…
new_record, change_info = zone.create_a_record(
name = TARGET_RRSET_NAME,
values = [home_ip],
ttl = 300
)
print('A record {} now points to {}'.format(
TARGET_RRSET_NAME, home_ip))
except route53.exceptions.Route53Error, exc:
print('Something went wrong')
print(exc)
sys.exit(1)
if __name__ == '__main__':
home_ip = scrape_home_ip()
main(home_ip)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment