Skip to content

Instantly share code, notes, and snippets.

@hamsolodev
Created October 17, 2014 01:19
Show Gist options
  • Save hamsolodev/3933fa0418acd045862c to your computer and use it in GitHub Desktop.
Save hamsolodev/3933fa0418acd045862c 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.
from __future__ import print_function
import os
import re
import sys
import requests
import route53
import route53.exceptions
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',
file=sys.stderr)
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.',
file=sys.stderr)
sys.exit(1)
def fetch_external_ip():
"""Use https://ip.appspot.com/ to determine external IP address.
"""
try:
req = requests.get('https://ip.appspot.com/', timeout=5)
except requests.exceptions.Timeout:
print('Service timed out!',
file=sys.stderr)
sys.exit(1)
except Exception, exc:
print('Something happened! ', exc,
file=sys.stderr)
sys.exit(1)
if req.status_code != 200:
print('Service returned {}!'.format(req.status_code),
file=sys.stderr)
sys.exit(1)
ip_addr = req.content.strip()
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),
file=sys.stderr)
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', exc,
file=sys.stderr)
sys.exit(1)
if __name__ == '__main__':
home_ip = fetch_external_ip()
main(home_ip)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment