Created
June 25, 2015 05:21
-
-
Save hurulu/772376182b8dac21a961 to your computer and use it in GitHub Desktop.
Update aws route 53
This file contains hidden or 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
| [dev] | |
| Access = | |
| Secret = | |
| Domain = a.edu.au | |
| [production] | |
| Access = | |
| Secret = | |
| Domain = a.org.au |
This file contains hidden or 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/python -d | |
| import boto, time,os | |
| import re,sys,string,ConfigParser | |
| from boto.route53.record import ResourceRecordSets | |
| from boto.route53.connection import Route53Connection | |
| #Define your environment | |
| env="production" | |
| default_ttl=300 | |
| def read_conf(mylist,filename,domain): | |
| conf = open(filename,"rb") | |
| for lines in conf: | |
| item = lines.rstrip("\r\n") | |
| comment_or_blank= re.match(r'^#.*|\s.*|^$', item) | |
| if not comment_or_blank: | |
| if item.split("\t")[0] == ".": | |
| name_type = domain+"_"+item.split("\t")[1] | |
| else: | |
| name_type = item.split("\t")[0]+"."+domain+"_"+item.split("\t")[1] | |
| values = item.split("\t")[2].split(",") | |
| mylist[name_type] = values | |
| conf.close | |
| def get_cred(conf,flag): | |
| cf = ConfigParser.ConfigParser() | |
| cf.read(conf) | |
| access = cf.get(flag,"Access") | |
| secret = cf.get(flag, "Secret") | |
| cred = { "access" : access, "secret" : secret} | |
| return cred | |
| def show_help(): | |
| print "Usage:\n"+sys.argv[0]+" COMMAND [yourdomain|yourfile]" | |
| print "COMMAND :" | |
| print " tolocal : Import yourdomain from route53 to you local file(conf.d/yourdomain)." | |
| print " toremote: Make your domain(the same as your file name) on route53 synchronized with yourfile/" | |
| print "Examples:" | |
| print sys.argv[0]+" tolocal sa.nectar.org.au" | |
| print sys.argv[0]+" toremote conf.d/sa.nectar.org.au." | |
| exit(1) | |
| def sync_to_local(mydomain,cred): | |
| print "Importing configuration file conf.d/"+mydomain+" from route 53 ..." | |
| mydomain = mydomain+"." | |
| dns = Route53Connection(cred["access"], cred["secret"]) | |
| zone = dns.get_hosted_zone_by_name(mydomain) | |
| zone_id = zone["GetHostedZoneResponse"]["HostedZone"]["Id"].split("/")[2] | |
| writefile = open("conf.d/"+mydomain,"w") | |
| count = 0 | |
| for record in dns.get_all_rrsets(zone_id): | |
| rname = str(record).split(":")[1].replace(mydomain,'') | |
| if len(rname) == 0: | |
| rname = "." | |
| else: | |
| rname = rname.rstrip('.') | |
| rtype = str(record).split(":")[2] | |
| rvalues = str(record).split(":")[3].replace('>','') | |
| writefile.write(rname + "\t" + rtype+ "\t" + rvalues+"\n") | |
| count += 1 | |
| writefile.close() | |
| print str(count) + " records imported" | |
| exit(0) | |
| def sync_to_remote(myfile,cred): | |
| domain = os.path.basename(myfile) | |
| print "Synchronizing "+ domain +" on route53 from "+myfile+" ..." | |
| print "-------------------------------------------------------------------------------------------------------" | |
| local_conf = "conf.d/"+domain | |
| local_list = {} #Store local records | |
| remote_list = {} #store route53 records | |
| read_conf(local_list,local_conf,domain) | |
| dns = Route53Connection(cred["access"], cred["secret"]) | |
| zone = dns.get_hosted_zone_by_name(domain) | |
| zone_id = zone["GetHostedZoneResponse"]["HostedZone"]["Id"].split("/")[2] | |
| #Get route53 records and copy them to remote_list, delete records that not in local_list | |
| delete_num = 0 | |
| for record in dns.get_all_rrsets(zone_id): | |
| rsets = ResourceRecordSets(dns, zone_id) | |
| rname = str(record).split(":")[1] | |
| rtype = str(record).split(":")[2] | |
| rvalues = str(record).split(":")[3].replace('>','').split(",") | |
| #delete records in route53 | |
| if not local_list.has_key(rname+"_"+rtype): | |
| change = rsets.add_change_record('DELETE',record) | |
| rsets.commit() | |
| delete_num += 1 | |
| print "DELETED : "+rname+" "+ rtype+" "+str(rvalues) | |
| else: | |
| remote_list[rname+"_"+rtype] = rvalues | |
| #Compare local records and remote records and copy the same records to to_remain | |
| to_remain = [] #records in this list are the same in both local and remote, hence no further operations needed. | |
| for key in local_list.iterkeys(): | |
| if remote_list.has_key(key): | |
| local_list[key].sort() | |
| remote_list[key].sort() | |
| if local_list[key] == remote_list[key]: | |
| to_remain.append(key) | |
| #Remove the same records from both local_list and remote_list because they do need any change | |
| for key in to_remain: | |
| del local_list[key] | |
| del remote_list[key] | |
| #Add or update records according to local_list | |
| add_num = 0 | |
| update_num = 0 | |
| for key in local_list.iterkeys(): | |
| rsets = ResourceRecordSets(dns, zone_id) | |
| rname = key.split("_")[0] | |
| rtype = key.split("_")[1] | |
| #add records to route 53, if they are not in remote_list | |
| if not remote_list.has_key(key): | |
| change = rsets.add_change('CREATE', rname,rtype,default_ttl) | |
| for value in local_list[key]: | |
| change.add_value(value) | |
| rsets.commit() | |
| add_num += 1 | |
| print "ADDED : "+rname+" "+ rtype+" "+str(local_list[key]) | |
| else: | |
| #Update records in route 53, if they are in both local_list and remote_list | |
| change = rsets.add_change('DELETE', rname,rtype) | |
| for value in remote_list[key]: | |
| change.add_value(value) | |
| change = rsets.add_change('CREATE', rname,rtype,default_ttl) | |
| for value in local_list[key]: | |
| change.add_value(value) | |
| rsets.commit() | |
| update_num += 1 | |
| print "UPDATED : "+rname+" "+ rtype+" "+str(local_list[key]) | |
| print "-------------------------------------------------------------------------------------------------------" | |
| print "SUMMARY : "+ str(delete_num) + " deleted / " + str(add_num) + " added / " + str(update_num) + " updated" | |
| #print local_list | |
| #print remote_list | |
| def main(): | |
| cred = get_cred("cred.conf",env) | |
| if len(sys.argv) == 3: | |
| if sys.argv[1] == "tolocal": | |
| sync_to_local(sys.argv[2],cred) | |
| elif sys.argv[1] == "toremote": | |
| sync_to_remote(sys.argv[2],cred) | |
| else: | |
| show_help() | |
| else: | |
| show_help() | |
| if __name__ == "__main__": | |
| main() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment