Created
July 2, 2013 06:29
-
-
Save hamsolodev/5907154 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/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