Last active
August 29, 2015 14:01
-
-
Save Duologic/8c12be99cb591ececfc5 to your computer and use it in GitHub Desktop.
r53updater.py
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
| from boto import route53 | |
| class R53Updater(object): | |
| """ | |
| Example for A record: | |
| r53 = R53Updater() | |
| r53.connect() | |
| records = r53.find_record('example.org') | |
| new_ip_list = ['1.2.3.4', '4.3.2.1'] | |
| r53.update_record(records[0], new_ip_list) | |
| """ | |
| def connect(self): | |
| """ | |
| Setup connection to AWS Route53 | |
| """ | |
| self.conn = route53.connect_to_region('eu-west-1') | |
| def get_zone_ids(self, domainnames): | |
| """ | |
| Get zone ids of a list of domainnames | |
| Returns a dict of lists | |
| Might contain more zone ids per domain if not fully qualified domainname | |
| """ | |
| all_zones = self.conn.get_all_hosted_zones() | |
| ret = {} | |
| for domainname in domainnames: | |
| ret[domainname] = [] | |
| for zone in all_zones.get('ListHostedZonesResponse').get('HostedZones'): | |
| if zone['Name'].startswith(domainname): | |
| ret[domainname].append(zone['Id'].split('/')[2]) | |
| return ret | |
| def get_recordsets(self, zone_id=None, cached=None): | |
| """ | |
| Get the recordsets | |
| Default, returns the whole list of RecordSets in this account | |
| zone_id: returns a list with that single RecordSet | |
| cached: if cached, returns a list of the cached RecordSets | |
| """ | |
| key_all_zones = "all_zones" | |
| if zone_id is None: | |
| zid = key_all_zones | |
| else: | |
| zid = zone_id | |
| if not hasattr(self, 'rrsets'): | |
| self.rrsets = {} | |
| else: | |
| if zid in self.rrsets.keys() and cached is None: | |
| return self.rrsets[zid] | |
| if zid != key_all_zones: | |
| rrsets = [self.conn.get_all_rrsets(zone_id),] | |
| else: | |
| all_zones = self.conn.get_all_hosted_zones() | |
| rrsets = [] | |
| for zone in all_zones.get('ListHostedZonesResponse').get('HostedZones'): | |
| rrsets.append(self.conn.get_all_rrsets(zone.get('Id').split('/')[2])) | |
| self.rrsets[zid] = rrsets | |
| return self.rrsets[zid] | |
| def find_record(self, hostname, rtype=None, zone_id=None, cached=None): | |
| """ | |
| Finds records according to its hostname | |
| Default, returns a list of tuples (Record, RecordSet) of type 'A' | |
| rtype: returns Default but with this type | |
| zone_id: see self.get_recordsets | |
| cached: see self.get_recordsets | |
| """ | |
| if rtype is None: | |
| rtype = 'A' | |
| found_records = [] | |
| for recordset in self.get_recordsets(zone_id=zone_id, cached=cached): | |
| for record in recordset: | |
| for res in record.resource_records: | |
| if record.type == rtype and res.startswith(hostname): | |
| found_records.append((record, recordset)) | |
| if record.type == rtype and record.name.startswith(hostname): | |
| found_records.append((record, recordset)) | |
| return found_records | |
| def create_record(self, zonename, rname, rtype, values, ttl=300): | |
| """ | |
| Creates a new Record | |
| Returns a ChangeResourceRecordSetsResponse | |
| zonename: a string that can return a single zone | |
| rname: a string with a FQDN | |
| rtype: a string with a record type like A, TXT, CNAME, ... | |
| values: list of values of for this Record | |
| ttl: time to live value | |
| """ | |
| zone_ids = self.get_zone_ids([zonename]) | |
| if len(zone_ids[zonename])<>1: | |
| raise Exception('Too many zones returned, can only be one') | |
| zone_id = zone_ids[zonename][0] | |
| recordsets = self.get_recordsets(zone_id, cached=False) | |
| if len(recordsets)<>1: | |
| raise Exception('Too many recordsets returned, can only be one') | |
| recordset = recordsets[0] | |
| found_records = self.find_record(rname, rtype, zone_id) | |
| if len(found_records): | |
| raise Exception('Record already exists') | |
| new_record = route53.record.Record(name=rname, | |
| type=rtype, | |
| ttl=ttl, | |
| resource_records=values) | |
| recordset.add_change_record("CREATE", new_record) | |
| return recordset.commit() | |
| def update_record(self, recordtuple, values): | |
| """ | |
| Updates a Record | |
| Returns a ChangeResourceRecordSetsResponse | |
| recordtuple: (Record, RecordSet) | |
| values: list of values of for this Record | |
| """ | |
| record, recordset = recordtuple | |
| new_record = route53.record.Record(name=record.name, | |
| type=record.type, | |
| ttl=300, | |
| resource_records=values, | |
| alias_hosted_zone_id=record.alias_hosted_zone_id) | |
| recordset.add_change_record("DELETE", record) | |
| recordset.add_change_record("CREATE", new_record) | |
| return recordset.commit() | |
| def delete_record(self, recordtuple): | |
| """ | |
| Deletes a Record | |
| Returns a ChangeResourceRecordSetsResponse | |
| recordtuple: (Record, RecordSet) | |
| """ | |
| record, recordset = recordtuple | |
| recordset.add_change_record("DELETE", record) | |
| return recordset.commit() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment