def load(con, zone_name, filename): zone = get_or_create_zone(con, zone_name) existing_records = comparable(skip_apex_soa_ns(zone, con.get_all_rrsets(zone['id']))) desired_records = comparable(skip_apex_soa_ns(zone, read_records(con, zone, filename))) to_delete = existing_records.difference(desired_records) to_add = desired_records.difference(existing_records) if to_add or to_delete: changes = ResourceRecordSets(con, zone['id']) for record in to_delete: change = changes.add_change('DELETE', **record.to_change_dict()) print "DELETE", record.name, record.type for value in record.resource_records: change.add_value(value) for record in to_add: change = changes.add_change('CREATE', **record.to_change_dict()) print "CREATE", record.name, record.type for value in record.resource_records: change.add_value(value) print "Applying changes..." changes.commit() print "Done." else: print "No changes."
def update_alias(zone_id): conn = get_connection() zone = get_zone(zone_id, conn) error = None form = RecordAliasForm(request.values, csrf_enabled=False) if form.validate_on_submit(): changes = ResourceRecordSets(conn, zone_id, form.comment.data) change = changes.add_change("DELETE", form.name.data, form.type.data, form.ttl.data) change.set_alias(form.alias_hosted_zone_id.data, form.alias_dns_name.data) change = changes.add_change("CREATE", form.name.data, form.type.data, form.ttl.data) change.set_alias(form.alias_hosted_zone_id.data, form.alias_dns_name.data) changes.commit() flash('Updated alias %s for %s' % (form.type.data, form.name.data)) return redirect(url_for('zones.detail', zone_id=zone_id)) elbs = get_connection('elb').get_all_load_balancers() return render_template('records/update_alias.html', form=form, zone=zone, zone_id=zone_id, error=error, elbs=elbs)
def test_use_health_check_in_resource_record_set(): conn = boto.connect_route53('the_key', 'the_secret') check = HealthCheck( ip_addr="10.0.0.25", port=80, hc_type="HTTP", resource_path="/", ) check = conn.create_health_check( check)['CreateHealthCheckResponse']['HealthCheck'] check_id = check['Id'] zone = conn.create_hosted_zone("testdns.aws.com") zone_id = zone["CreateHostedZoneResponse"][ "HostedZone"]["Id"].split("/")[-1] changes = ResourceRecordSets(conn, zone_id) change = changes.add_change( "CREATE", "foo.bar.testdns.aws.com", "A", health_check=check_id) change.add_value("1.2.3.4") changes.commit() record_sets = conn.get_all_rrsets(zone_id) record_sets[0].health_check.should.equal(check_id)
def update_route53_record(conn, ip_address, hostname, domain): hosted_zone_name = domain if domain.endswith('.') else domain + '.' zone = conn.get_hosted_zone_by_name(hosted_zone_name) zone_id = zone['GetHostedZoneResponse']['HostedZone']['Id'].split('/')[2] rrsets = conn.get_all_rrsets(zone_id, type='A', name=hostname + '.' + hosted_zone_name) changes = ResourceRecordSets(conn, zone_id) if len(rrsets) != 0: for rrset in rrsets: # For some stupid reason Route53 will return RRsets that have nothing # to do with what we asked for, so this checks to be sure we're working # with the RRset we asked for. if rrset.type == 'A' and rrset.name == hostname + '.' + hosted_zone_name: change = changes.add_change('DELETE', rrset.name, rrset.type) for rr in rrset.resource_records: change.add_value(rr) change = changes.add_change('CREATE', hostname + '.' + hosted_zone_name, 'A') change.add_value(ip_address) try: ret = changes.commit() except boto.route53.exception.DNSServerError as e: sys.stderr.write('Error: Failed to update RRs\n %s' % e) return False return True
def test_use_health_check_in_resource_record_set(): conn = boto.connect_route53("the_key", "the_secret") check = HealthCheck(ip_addr="10.0.0.25", port=80, hc_type="HTTP", resource_path="/") check = conn.create_health_check( check)["CreateHealthCheckResponse"]["HealthCheck"] check_id = check["Id"] zone = conn.create_hosted_zone("testdns.aws.com") zone_id = zone["CreateHostedZoneResponse"]["HostedZone"]["Id"].split( "/")[-1] changes = ResourceRecordSets(conn, zone_id) change = changes.add_change("CREATE", "foo.bar.testdns.aws.com", "A", health_check=check_id) change.add_value("1.2.3.4") changes.commit() record_sets = conn.get_all_rrsets(zone_id) record_sets[0].health_check.should.equal(check_id)
def create_record(self, name, value, identifier=None, weight=None): changes = ResourceRecordSets(self.route53, self.zone_id) change = changes.add_change("CREATE", name + ".", "CNAME", 60, identifier=identifier, weight=weight) change.add_value(value) changes.commit()
def remove_domain(): conn = boto.connect_route53() changes = ResourceRecordSets(conn, env.hosted_zone_id) for url in env.urls: change = changes.add_change("DELETE", url, "CNAME") change.add_value(env.public_host) changes.commit()
def update(zone_id): conn = get_connection() zone = get_zone(zone_id, conn) form = EditRecordForm(request.values) error = None if request.method == "GET" and not form.values: return redirect(url_for('.update_alias', zone_id=zone_id, **request.values.to_dict())) if request.method == "POST": changes = ResourceRecordSets(conn, zone_id, form.comment.data) del_change = changes.add_change("DELETE", form.previous_name.data, form.previous_type.data, form.previous_ttl.data) [del_change.add_value(v) for v in form.previous_values] change = changes.add_change("CREATE", form.name.data, form.type.data, form.ttl.data) [change.add_value(v) for v in form.values] changes.commit() flash('Updated %s record for %s' % (form.type.data, form.name.data)) return redirect(url_for('zones.detail', zone_id=zone_id)) return render_template('records/update.html', form=form, zone=zone, zone_id=zone_id, error=error)
def modify_dns(self, domain, dest_ip): """ Modify DNS A record. :type domain: dict :param domain: Domain to change including their information. :type dest_ip: string :param dest_ip: Destination IP address. :rtype: dict :return: ResourceRecordSets object. """ domain_name = domain['name'] rrs = ResourceRecordSets(self.route53_conn, domain['aws_zone_id']) current_dns = self.get_current_dns(domain['aws_zone_id'], domain_name) if current_dns[domain_name]['destination'] == dest_ip: return False #change domain change = rrs.add_change("DELETE", domain_name, "A", 300) change.add_value(current_dns[domain_name]['destination']) change = rrs.add_change("CREATE", domain_name, "A", 300) change.add_value(dest_ip) return rrs.commit()
def change_alias(conn, hosted_zone_id, name, type, new_alias_hosted_zone_id, new_alias_dns_name, identifier=None, weight=None, comment=""): """Delete and then add an alias to a zone. identifier and weight are optional.""" from boto.route53.record import ResourceRecordSets changes = ResourceRecordSets(conn, hosted_zone_id, comment) # Assume there are not more than 10 WRRs for a given (name, type) responses = conn.get_all_rrsets(hosted_zone_id, type, name, maxitems=10) for response in responses: if response.name != name or response.type != type: continue if response.identifier != identifier or response.weight != weight: continue change1 = changes.add_change("DELETE", name, type, identifier=response.identifier, weight=response.weight) change1.set_alias(response.alias_hosted_zone_id, response.alias_dns_name) change2 = changes.add_change("CREATE", name, type, identifier=identifier, weight=weight) change2.set_alias(new_alias_hosted_zone_id, new_alias_dns_name) print(changes.commit())
def update_alias_record(self, old_record, new_identifier=None, alias_dns_name=None, comment=""): """ Update an existing alias record in this Zone. Returns a Status object. :type old_record: ResourceRecord :param old_record: A ResourceRecord (e.g. returned by find_records) See _new_alias_record for additional parameter documentation. """ record = copy.copy(old_record) changes = ResourceRecordSets(self.route53connection, self.id, comment) changes.add_change_record("DELETE", record) if alias_dns_name: self._new_alias_record(changes, record.type, record.name, new_identifier, record.alias_hosted_zone_id, alias_dns_name, comment) else: self._new_alias_record(changes, record.type, record.name, new_identifier, record.alias_hosted_zone_id, record.alias_dns_name, comment) return Status(self.route53connection, self._commit(changes))
def update_elb_dns(stack, elb_attr, hosted_zone_id, dns_name): ttl = 60 elb_dns = cf.get_stack_output_value(stack, elb_attr) dns_record_name = dns_name + "." conn = boto.connect_route53() existing_entries = conn.get_all_rrsets(hosted_zone_id, "CNAME", dns_name) changes = ResourceRecordSets(conn, hosted_zone_id) for item in existing_entries: if dns_record_name != item.name: logging.info('Nothing to change for %s', dns_name) continue for record in item.resource_records: logging.warning('Deleting CNAME entry {0} -> {1}'.format(dns_name, record)) change = changes.add_change("DELETE", dns_name, "CNAME", ttl=ttl) change.add_value(record) logging.warning("Adding CNAME entry %s -> %s", dns_name, elb_dns) change = changes.add_change("CREATE", dns_name, "CNAME", ttl=ttl) change.add_value(elb_dns) try: changes.commit() print '*** DNS record updated' print '{0} IN CNAME {1}'.format(dns_name, elb_dns) except Exception, e: logging.error(e)
def main(): args = options() route53_ips = get_route53(args) ec2_ips = get_ec2(args) report_ips = {} conn = Route53Connection() changes = ResourceRecordSets(conn, args.zoneid) print 'Following records will be deleted.' for name, ip in route53_ips.items(): match = 0 for ec2_id in ec2_ips: if ip in ec2_ips[ec2_id].values(): match = 1 if match == 0: report_ips[name] = ip for name, ip in sorted(report_ips.items()): if re.match('[\d\.]+', ip): print "A;%s;%s" % (ip, name) change = changes.add_change("DELETE", str(name), "A", 300) change.add_value(ip) else: print "CNAME;%s;%s" % (ip, name) changes.commit() print 'Deleted records: ' pprint.pprint(changes)
def create_record(self, name, value): print "create_record" changes = ResourceRecordSets(self.route53, self.zone_id) change = changes.add_change("CREATE", name + ".", "CNAME", 60) change.add_value(value) changes.commit()
def create_record(name, value, type, zone): """Create DNS entries in route53""" conn = boto.connect_route53() change_set = ResourceRecordSets(conn, zone) change = change_set.add_change("CREATE", name, type) change.add_value(value) result = change_set.commit()
def remove_domain(): conn = boto.connect_route53() changes = ResourceRecordSets(conn, env.hosted_zone_id) for url in env.urls: change = changes.add_change("DELETE", url,"CNAME") change.add_value(env.public_host) changes.commit()
def _add_del_alias(conn, hosted_zone_id, change, name, type, identifier, weight, alias_hosted_zone_id, alias_dns_name, comment): from boto.route53.record import ResourceRecordSets changes = ResourceRecordSets(conn, hosted_zone_id, comment) change = changes.add_change(change, name, type, identifier=identifier, weight=weight) change.set_alias(alias_hosted_zone_id, alias_dns_name) print changes.commit()
def _uninstall(self): logger = self.get_logger('uninstall') self.terminate_instances() service_map = dict((s.name, s) for s in self.services) if self.route53_hosted_zone_id and self.route53_records: changeset = ResourceRecordSets( self.app.route53_connection, self.route53_hosted_zone_id, 'Changed by Asuka: {0}, {1} [clean]'.format(self.app.name, self.branch.label) ) from .service import DomainService for service_name, domain_format in self.route53_records.items(): service = service_map[service_name] if not isinstance(service, DomainService): raise TypeError(repr(service) + 'is not an instance of ' 'crosspop.service.DomainService') domain = domain_format.format(branch=self.branch) service.remove_domain(domain, changeset) if changeset.changes: logger.info('Route 53 changeset:\n%s', changeset.to_xml()) changeset.commit() for name, service in service_map.iteritems(): logger.info('Uninstall %s...', name) service.uninstall() logger.info('Uninstalled %s', name)
def update_dns(self, host_name, ip_address): ttl = 10 host_name = ".".join([host_name, self.domain]) conn = boto.connect_route53() response = conn.get_all_rrsets(self.hosted_zone_id, 'A', host_name, maxitems=1) if len(response): response = response[0] comment = "Starcluster route53 plugin deleted record for %s" % ( host_name) changes = ResourceRecordSets(conn, self.hosted_zone_id, comment) change1 = changes.add_change("DELETE", host_name, 'A', response.ttl) for old_value in response.resource_records: change1.add_value(old_value) try: changes.commit() log.info(comment) except Exception as e: log.warning(e) comment = "Starcluster route53 plugin updated record for %s to %s" % ( host_name, ip_address) changes = ResourceRecordSets(conn, self.hosted_zone_id, comment) change2 = changes.add_change("CREATE", host_name, 'A', ttl) change2.add_value(ip_address) try: changes.commit() log.info(comment) except Exception as e: log.warning(e)
def update_record(self, hosted_zone_id, names, type, resource_records, ttl=600, identifier=None, weight=None, comment=""): """Delete and then add a record to a zone""" conn = self._get_checked_connection() changes = ResourceRecordSets(conn, hosted_zone_id, comment) if isinstance(names, basestring): names = [names] if isinstance(resource_records, basestring): resource_records = [resource_records] for name in names: # Assume there are not more than 10 WRRs for a given (name, type) rs = conn.get_all_rrsets(hosted_zone_id, type, name, maxitems=10) for record in rs: if record.name != name or record.type != type: continue if record.identifier != identifier or record.weight != weight: continue delete_record = changes.add_change( "DELETE", name, type, record.ttl, identifier=identifier, weight=weight) for value in record.resource_records: delete_record.add_value(value) create_record = changes.add_change( "CREATE", name, type, ttl, identifier=identifier, weight=weight) for value in resource_records: create_record.add_value(value) return changes.commit()
def test_create_resource_record_set(self): hc = HealthCheck(ip_addr="54.217.7.118", port=80, hc_type="HTTP", resource_path="/testing") result = self.conn.create_health_check(hc) records = ResourceRecordSets(connection=self.conn, hosted_zone_id=self.zone.id, comment='Create DNS entry for test') change = records.add_change( 'CREATE', 'unittest.%s.' % self.base_domain, 'A', ttl=30, identifier='test', weight=1, health_check=result['CreateHealthCheckResponse']['HealthCheck'] ['Id']) change.add_value("54.217.7.118") records.commit() records = ResourceRecordSets(self.conn, self.zone.id) deleted = records.add_change( 'DELETE', "unittest.%s." % self.base_domain, "A", ttl=30, identifier='test', weight=1, health_check=result['CreateHealthCheckResponse']['HealthCheck'] ['Id']) deleted.add_value('54.217.7.118') records.commit()
def load(con, zone_name, file_in, **kwargs): ''' Send DNS records from input file to Route 53. Arguments are Route53 connection, zone name, vpc info, and file to open for reading. ''' vpc = kwargs.get('vpc', {}) zone = get_zone(con, zone_name, vpc) if not zone: zone = create_zone(con, zone_name, vpc) existing_records = comparable(skip_apex_soa_ns(zone, con.get_all_rrsets(zone['id']))) desired_records = comparable(skip_apex_soa_ns(zone, read_records(file_in))) to_delete = existing_records.difference(desired_records) to_add = desired_records.difference(existing_records) if to_add or to_delete: changes = ResourceRecordSets(con, zone['id']) for record in to_delete: change = changes.add_change('DELETE', **record.to_change_dict()) print "DELETE", record.name, record.type for value in record.resource_records: change.add_value(value) for record in to_add: change = changes.add_change('CREATE', **record.to_change_dict()) print "CREATE", record.name, record.type for value in record.resource_records: change.add_value(value) print "Applying changes..." changes.commit() print "Done." else: print "No changes."
def add_to_slave_cname_pool(self): """ Add this instance to the pool of hostnames for slave.<cluster name>.goteam.be. This is a pool of 'weighted resource recordsets', which allows traffic to be distributed to multiple read-slaves. """ route53_conn = self._get_route53_conn() changes = ResourceRecordSets(route53_conn, settings.ROUTE53_ZONE_ID) self.logger.info('Adding %s to CNAME pool for %s' % (self.metadata['instance-id'], self.slave_cname)) add_record = changes.add_change('CREATE', self.slave_cname, 'CNAME', ttl=settings.SLAVE_CNAME_TTL, weight='10', identifier=self.metadata['instance-id']) add_record.add_value(self.metadata['public-hostname']) try: changes.commit() except boto.route53.exception.DNSServerError, e: if e.error_message is not None and e.error_message.endswith('it already exists'): # This instance is already in the pool - carry on as normal. self.logger.warning('Attempted to create a CNAME, but one already exists for this instance') else: raise
def update_type_A_domain(self, domain, point_to): """Update DNS domain record""" r53 = self.connections.get_route53() # Get Zone ID zone = r53.get_zone(self.env.domain) zone_id = zone.id if not zone.get_a(domain): sys.exit("\nAbort: {} does not exists! " \ "Please create first!".format(domain)) # Commit change try: changes = ResourceRecordSets(connection=r53, hosted_zone_id=zone_id) change = changes.add_change(action='UPSERT', name=domain, type="A") change.set_alias( alias_hosted_zone_id=zone_id, alias_dns_name=point_to, alias_evaluate_target_health=False) changes.commit() except DNSServerError: raise except Exception: print("Unexpected error: {}".format(traceback.format_exc())) sys.exit(1) # Print record set record = zone.get_a(domain) print("\nUpdated record set is:\n{}".format(record.to_print()))
def delete_route53_record(name): ''' Deletes a record! ''' # NOTICE: Our registered DNS aliases have a "pub-" prefix. # Our instance names do not. route53_ip = get_route53_ip(name) logging.info("%s, IP=%s" % (name, route53_ip)) conn = connect_route53() changes = ResourceRecordSets(conn, zone_id) logging.info("DELETE %s, IP=%s, TTL=%s" % (name, route53_ip, ttl)) if options.dryrun is True: return # Delete old record if it exists if route53_ip is not None: # NOTE: TTL is 300. But it must match in the record or this fails. change1 = changes.add_change("DELETE", name, "A", ttl=ttl) change1.add_value(route53_ip) result = changes.commit() # Note: If delete&create this commit does both in one transaction. print "Delete %s, IP=%s" % (name, route53_ip) else: print "No record match found." return
def create_route53_zone(conn, zone_name): """ Create's the given zone_name if it doesn't already exists. Also sets the SOA negative caching TTL to something short (300 seconds). """ if not zone_name.endswith('.'): zone_name += '.' zone = conn.get_zone(zone_name) if not zone: logger.debug("Zone %s does not exist, creating.", zone_name) zone = conn.create_zone(zone_name) # Update SOA to lower negative caching value soa = zone.find_records(zone_name, 'SOA') old_soa_body = soa.resource_records[0] old_soa_parts = old_soa_body.split(' ') # If the negative cache value is already 300, don't update it. if old_soa_parts[-1] == '300': return logger.debug("Updating negative caching value on zone %s to 300.", zone_name) new_soa_body = ' '.join(old_soa_body.split(' ')[:-1]) + ' 300' changes = ResourceRecordSets(conn, zone.id) delete_soa = changes.add_change('DELETE', zone.name, 'SOA', soa.ttl) delete_soa.add_value(old_soa_body) create_soa = changes.add_change('CREATE', zone.name, 'SOA', soa.ttl) create_soa.add_value(new_soa_body) changes.commit()
def add_to_slave_cname_pool(self): """ Add this instance to the pool of hostnames for slave.<cluster name>.goteam.be. This is a pool of 'weighted resource recordsets', which allows traffic to be distributed to multiple read-slaves. """ route53_conn = self._get_route53_conn() changes = ResourceRecordSets(route53_conn, settings.ROUTE53_ZONE_ID) self.logger.info('Adding %s to CNAME pool for %s' % (self.metadata['instance-id'], self.slave_cname)) add_record = changes.add_change( 'CREATE', self.slave_cname, 'CNAME', ttl=settings.SLAVE_CNAME_TTL, weight='10', identifier=self.metadata['instance-id']) add_record.add_value(self.metadata['public-hostname']) try: changes.commit() except boto.route53.exception.DNSServerError, e: if e.error_message is not None and e.error_message.endswith( 'it already exists'): # This instance is already in the pool - carry on as normal. self.logger.warning( 'Attempted to create a CNAME, but one already exists for this instance' ) else: raise
def create_dns_record(hostname, hostip): from boto.route53.record import ResourceRecordSets conn = boto.connect_route53() edits = ResourceRecordSets(conn, ZONE_ID) edit = edits.add_change("CREATE", hostname.strip() + HOSTNAME_POSTFIX, "CNAME") edit.add_value(hostip) status = edits.commit()
def add_r53_record(self, fqdn, type, value, ttl=60): """Add a record to Route53""" r53 = self.get_r53() zone_id = self.find_r53_zone_for(fqdn) changes = ResourceRecordSets(r53, zone_id) change = changes.add_change("CREATE", fqdn, type, ttl) change.add_value(value) changes.commit()
def _addRR(self, rectype, host, ip, ttl=300): if self.zoneid is not None: if self.changes is None: self.changes = ResourceRecordSets(self.ar53, self.zoneid) change = self.changes.add_change("CREATE", host, rectype, ttl) change.add_value(ip) else: print "Zone not set, or does not exist in DNS"
def delete_r53_record(self, fqdn, type, value, ttl=60): """Remove a record from Route53""" r53 = self.get_r53() zone_id = self.find_r53_zone_for(fqdn) changes = ResourceRecordSets(r53, _r53_zone_id) change = changes.add_change("DELETE", fqdn, type, ttl) change.add_value(value) changes.commit()
def _add_del(conn, hosted_zone_id, change, name, type, identifier, weight, values, ttl, comment): from boto.route53.record import ResourceRecordSets changes = ResourceRecordSets(conn, hosted_zone_id, comment) change = changes.add_change(change, name, type, ttl, identifier=identifier, weight=weight) for value in values.split(','): change.add_value(value) print changes.commit()
def _changeAlias(self, change, name, recordType, aliasHostedZoneId, aliasDNSName, identifier, weight, comment): logging.info('%s alias %s:%s in zone %s', change, name, recordType, self.domain) changes = ResourceRecordSets(self.connection, self.id, comment) change = changes.add_change(change, name, recordType, identifier=identifier, weight=weight) change.set_alias(aliasHostedZoneId, aliasDNSName) changes.commit()
def add_cname(zone_id, src, dest, _type='CNAME'): app.logger.info("Add cname: {}, {}, {}, {}".format(zone_id, src, dest, _type)) conn = boto.connect_route53(app.config['aws']['key'], app.config['aws']['secret']) changes = ResourceRecordSets(conn, zone_id, '') change = changes.add_change("CREATE", dest, _type, 300) change.add_value(src) changes.commit()
def new_domain(self, main_domain, domain): conn = boto.connect_route53(self.aws_access_key_id, self.aws_secret_access_key) changes = ResourceRecordSets(conn, self.hosted_zone_id) self.cname_change(changes, main_domain, domain, 'UPSERT') self.a_change(changes, main_domain, domain, 'UPSERT') self.services_change(changes, main_domain, 'UPSERT', domain.services) changes.commit()
def delete_route_to_bucket(self, bucket_name, region='us-east-1'): s3zone = s3zones[region] changes = ResourceRecordSets(self.connection, self.zone.id) change = changes.add_change('DELETE', bucket_name + '.', 'A', alias_dns_name='s3-website-'+ region + '.amazonaws.com.', alias_hosted_zone_id=s3zone) changes.commit()
def delete_cname(zone_id, src, dest): conn = boto.connect_route53(app.config['aws']['key'], app.config['aws']['secret']) changes = ResourceRecordSets(conn, zone_id, '') change = changes.add_change('DELETE', dest, 'CNAME', 300) change.set_alias(None, None) change.add_value(src) changes.commit()
def r53_change_record( name, values, aws_access_key_id, aws_secret_access_key, proxy=None, proxy_port=None, type="A", ttl="600", comment="", ): # note: if the network is unreachable this function will retry, # blocking up to one minute before the last retry (not configurable?) conn = boto.connect_route53( aws_access_key_id=aws_access_key_id, aws_secret_access_key=aws_secret_access_key, proxy=proxy, proxy_port=proxy_port, ) res = conn.get_all_hosted_zones() domain_name = re.sub("^[^\.]*\.", "", name) if name[0] == ".": name = name[1:] hosted_zone_id = None for zoneinfo in res["ListHostedZonesResponse"]["HostedZones"]: zonename = zoneinfo["Name"] _zone_id = zoneinfo["Id"] _zone_id = re.sub("/hostedzone/", "", _zone_id) if zonename[-1] == ".": zonename = zonename[:-1] # print domain_name, zonename if domain_name == zonename: hosted_zone_id = _zone_id break if not hosted_zone_id: raise RuntimeError( "domain_name " + repr(domain_name) + " not found in hosted zones" ) changes = ResourceRecordSets(conn, hosted_zone_id, comment) response = conn.get_all_rrsets(hosted_zone_id, type, name, maxitems=1) if response: rrset = response[0] change1 = changes.add_change("DELETE", name, type, rrset.ttl) for old_value in rrset.resource_records: change1.add_value(old_value) change2 = changes.add_change("CREATE", name, type, ttl) for new_value in values.split(","): change2.add_value(new_value) return changes.commit()
def host_zone_create(route53, host_zone_id, host_zone_AND_ip, silent=0): #调用函数获取域名所有信息和域名所有记录 host_zone_info, host_zone_rrsets_dicts = host_zone_info_single(host_zone_id, 1) #实例化records changes = ResourceRecordSets(route53, host_zone_id, '') #分割参数 host_zone:ip:... host_zone_delete_info = host_zone_AND_ip.split(':') #输出的系统信息初始化 out_put = "" #输入得参数是否与现有的dns记录匹配的标志 is_matched = 0 #循环所有记录词典 for record in host_zone_rrsets_dicts: #dns上记录是否与输入的记录 名匹配 if record['name'].strip('.') == host_zone_delete_info[0]: for record_ip in record['records']: if ',' in host_zone_delete_info[1]: host_zone_delete_ip_arr = host_zone_delete_info[1].split(',') if record_ip in host_zone_delete_ip_arr: record_ip == host_zone_delete_info[1] #修改标志位 is_matched = 1 out_put += 'Host zone 记录已存在,新建失败! %s %s %s\n' % (record['name'].strip('.'), record_ip, record['type']) #pending 删除 #chan = changes.add_change("DELETE", host_zone_delete_info[0], record['type'], record['ttl']) #chan.add_value(host_zone_delete_info[1]) #执行删除 #commit = changes.commit() break #IP是否匹配 elif record_ip == host_zone_delete_info[1]: #修改标志位 is_matched = 1 out_put += 'Host zone 记录已存在,新建失败! %s %s %s\n' % (record['name'].strip('.'), record_ip, record['type']) #pending 删除 #chan = changes.add_change("DELETE", host_zone_delete_info[0], record['type'], record['ttl']) #chan.add_value(host_zone_delete_info[1]) #执行删除 #commit = changes.commit() break #匹配检查,未匹配输出系统信息 if is_matched == 0: chan =changes.add_change('CREATE', host_zone_delete_info[0], host_zone_delete_info[2], ttl=host_zone_delete_info[3]) if ',' in host_zone_delete_info[1]: host_zone_delete_ip_arr = host_zone_delete_info[1].split(',') for host_zone_delete_ip_str in host_zone_delete_ip_arr: chan.add_value(host_zone_delete_ip_str) else: #out_put += "Host zone 记录与 参数不匹配\n" chan.add_value(host_zone_delete_info[1]) commit = changes.commit() #是否输出系统信息 静默标志位检查 if silent == 0: out(out_put) #返回是否成功 return is_matched
def add_record(self, resource_type, name, value, ttl=60, comment=""): """Add a new record to a zone""" changes = ResourceRecordSets(route53, self.id, comment) change = changes.add_change("CREATE", name, resource_type, ttl) if type(value) in [list, tuple, set]: for record in value: change.add_value(record) else: change.add_value(value) status = Status(changes.commit()['ChangeResourceRecordSetsResponse']['ChangeInfo'])
def _add_dns_record(self, hosted_zone, record_name, record_type, record_value, record_ttl=300, record_comment=''): from boto.route53.record import ResourceRecordSets conn = boto.connect_route53() zone = conn.get_zone(hosted_zone) changes = ResourceRecordSets(conn, zone.id, record_comment) change = changes.add_change('CREATE', '%s.%s' % (record_name, hosted_zone), record_type, record_ttl) change.add_value(record_value) # if not self.config['dry_run']: changes.commit()
def main(): # Get your public IP from the hypervisor # If you wish to use this on a non-AWS server, use http://ip.42.pl/raw instead current_ip = urllib2.urlopen('http://169.254.169.254/latest/meta-data/public-ipv4').read() # Avoid to hit the Route53 API if is not necessary. # so compare first to a DNS server if the IP changed resolved_ip = resolve_name_ip(DOMAIN_NAME) if resolved_ip == current_ip: logger.debug('DNS response (%s) and public IP (%s) are the same, nothing to do' % (resolved_ip, current_ip)) return conn = Route53Connection() try: zone = conn.get_hosted_zone(HOSTED_ZONE) except DNSServerError: logger.error('%s Zone Not Found' % HOSTED_ZONE) sys.exit(1) response = conn.get_all_rrsets(HOSTED_ZONE, 'A', DOMAIN_NAME, maxitems=1)[0] if current_ip not in response.resource_records: logger.info('Found new IP: %s' % current_ip) # Delete the old record, and create a new one. # This code is from route53.py script, the change record command changes = ResourceRecordSets(conn, HOSTED_ZONE, '') change1 = changes.add_change("DELETE", DOMAIN_NAME, 'A', response.ttl) for old_value in response.resource_records: change1.add_value(old_value) change2 = changes.add_change("CREATE", DOMAIN_NAME, 'A', response.ttl) change2.add_value(current_ip) try: commit = changes.commit() logger.debug('%s' % commit) except: logger.error("Changes can't be made: %s" % commit) sys.exit(1) else: change = conn.get_change(get_change_id(commit['ChangeResourceRecordSetsResponse'])) logger.debug('%s' % change) while get_change_status(change['GetChangeResponse']) == 'PENDING': time.sleep(2) change = conn.get_change(get_change_id(change['GetChangeResponse'])) logger.debug('%s' % change) if get_change_status(change['GetChangeResponse']) == 'INSYNC': logger.info('Change %s A de %s -> %s' % (DOMAIN_NAME, response.resource_records[0], current_ip)) else: logger.warning('Unknow status for the change: %s' % change) logger.debug('%s' % change)
def update_dns_cname_record(conn, zone_id, cname_record, cname_value): # zone_id = 'Z2IBYTQ6W9V2HA' # cname_record = 'sol1-salt1.devopslogic.com' result = None try: changes = ResourceRecordSets(conn, zone_id) change = changes.add_change("UPSERT", cname_record, "CNAME", 60) change.add_value(cname_value) result = changes.commit() except Exception, e: print "Exception: %s" % e
def delete_record(self, resource_type, name, value, ttl=None, comment=""): """Delete a record from a zone""" ttl = ttl or default_ttl changes = ResourceRecordSets(route53, self.id, comment) change = changes.add_change("DELETE", name, resource_type, ttl) if type(value) in [list, tuple, set]: for record in value: change.add_value(record) else: change.add_value(value) status = Status(changes.commit()['ChangeResourceRecordSetsResponse']['ChangeInfo'])
def test_add_change(self): rrs = ResourceRecordSets(self.conn, self.zone.id) created = rrs.add_change("CREATE", "vpn.%s." % self.base_domain, "A") created.add_value('192.168.0.25') rrs.commit() rrs = ResourceRecordSets(self.conn, self.zone.id) deleted = rrs.add_change('DELETE', "vpn.%s." % self.base_domain, "A") deleted.add_value('192.168.0.25') rrs.commit()
def cname(route53conn, zone, domain_name, alt_name, ttl=60, remove=False): from boto.route53.record import ResourceRecordSets zone_id = get_zone_id(zone) changes = ResourceRecordSets(route53conn, zone_id) change = changes.add_change("DELETE" if remove else "CREATE", name=domain_name, type="CNAME", ttl=ttl) if alt_name: change.add_value(alt_name) changes.commit()
def delete_record(self, name): changes = ResourceRecordSets(self.route53, self.zone_id) value = None sets = self.route53.get_all_rrsets(self.zone_id, None) for rset in sets: if rset.name == name + ".": value = rset.resource_records[0] if value != None: change = changes.add_change("DELETE", name + ".", "CNAME", 60) change.add_value(value) changes.commit()
def r53_change_record(name, values, aws_access_key_id, aws_secret_access_key, proxy=None, proxy_port=None, type="A", ttl="600", comment=""): # note: if the network is unreachable this function will retry, # blocking up to one minute before the last retry (not configurable?) conn = boto.connect_route53(aws_access_key_id=aws_access_key_id, aws_secret_access_key=aws_secret_access_key, proxy=proxy, proxy_port=proxy_port) res = conn.get_all_hosted_zones() domain_name = re.sub('^[^\.]*\.', '', name) if name[0] == '.': name = name[1:] hosted_zone_id = None for zoneinfo in res['ListHostedZonesResponse']['HostedZones']: zonename = zoneinfo['Name'] _zone_id = zoneinfo['Id'] _zone_id = re.sub('/hostedzone/', '', _zone_id) if zonename[-1] == '.': zonename = zonename[:-1] #print domain_name, zonename if domain_name == zonename: hosted_zone_id = _zone_id break if not hosted_zone_id: raise RuntimeError, 'domain_name ' + repr( domain_name) + ' not found in hosted zones' changes = ResourceRecordSets(conn, hosted_zone_id, comment) response = conn.get_all_rrsets(hosted_zone_id, type, name, maxitems=1) if response: rrset = response[0] change1 = changes.add_change("DELETE", name, type, rrset.ttl) for old_value in rrset.resource_records: change1.add_value(old_value) change2 = changes.add_change("CREATE", name, type, ttl) for new_value in values.split(','): change2.add_value(new_value) return changes.commit()
def test_alias_rrset(): conn = boto.connect_route53("the_key", "the_secret") zone = conn.create_hosted_zone("testdns.aws.com") zoneid = zone["CreateHostedZoneResponse"]["HostedZone"]["Id"].split( "/")[-1] changes = ResourceRecordSets(conn, zoneid) changes.add_change( "CREATE", "foo.alias.testdns.aws.com", "A", alias_hosted_zone_id="Z3DG6IL3SJCGPX", alias_dns_name="foo.testdns.aws.com", ) changes.add_change( "CREATE", "bar.alias.testdns.aws.com", "CNAME", alias_hosted_zone_id="Z3DG6IL3SJCGPX", alias_dns_name="bar.testdns.aws.com", ) changes.commit() rrsets = conn.get_all_rrsets(zoneid, type="A") alias_targets = [rr_set.alias_dns_name for rr_set in rrsets] alias_targets.should.have.length_of(2) alias_targets.should.contain("foo.testdns.aws.com") alias_targets.should.contain("bar.testdns.aws.com") rrsets[0].alias_dns_name.should.equal("foo.testdns.aws.com") rrsets[0].resource_records.should.have.length_of(0) rrsets = conn.get_all_rrsets(zoneid, type="CNAME") rrsets.should.have.length_of(1) rrsets[0].alias_dns_name.should.equal("bar.testdns.aws.com") rrsets[0].resource_records.should.have.length_of(0)
def test_rrset_with_multiple_values(): conn = boto.connect_route53("the_key", "the_secret") zone = conn.create_hosted_zone("testdns.aws.com") zoneid = zone["CreateHostedZoneResponse"]["HostedZone"]["Id"].split("/")[-1] changes = ResourceRecordSets(conn, zoneid) change = changes.add_change("CREATE", "foo.bar.testdns.aws.com", "A") change.add_value("1.2.3.4") change.add_value("5.6.7.8") changes.commit() rrsets = conn.get_all_rrsets(zoneid) rrsets.should.have.length_of(1) set(rrsets[0].resource_records).should.equal(set(["1.2.3.4", "5.6.7.8"]))
def test_set_alias_backwards_compatability(self): base_record = dict(name="alias.%s." % self.base_domain, type="A", identifier="boto:TestRoute53AliasResourceRecordSets") rrs = ResourceRecordSets(self.conn, self.zone.id) new = rrs.add_change(action="UPSERT", **base_record) new.set_alias(self.zone.id, "target.%s" % self.base_domain) rrs.commit() rrs = ResourceRecordSets(self.conn, self.zone.id) delete = rrs.add_change(action="DELETE", **base_record) delete.set_alias(self.zone.id, "target.%s" % self.base_domain) rrs.commit()
def _changeRecord(self, change, name, recordType, values, ttl): logging.info('%s record %s:%s in zone %s', change, name, recordType, self.domain) if type(values) is not types.ListType: values = [values] changes = ResourceRecordSets(self.connection, self.id) change = changes.add_change(change, name, recordType, ttl) for value in values: change.add_value(value) changes.commit()
def r53_change_record(name, values, aws_access_key_id, aws_secret_access_key, proxy=None, proxy_port=None, type="A", ttl="600", comment=""): conn = boto.connect_route53(aws_access_key_id=aws_access_key_id, aws_secret_access_key=aws_secret_access_key, proxy=proxy, proxy_port=proxy_port) res = conn.get_all_hosted_zones() domain_name = re.sub('^[^\.]*\.', '', name) if name[0] == '.': name = name[1:] hosted_zone_id = None for zoneinfo in res['ListHostedZonesResponse']['HostedZones']: zonename = zoneinfo['Name'] _zone_id = zoneinfo['Id'] _zone_id = re.sub('/hostedzone/', '', _zone_id) if zonename[-1] == '.': zonename = zonename[:-1] logging.debug("%s %s" % (domain_name, zonename)) if domain_name == zonename: hosted_zone_id = _zone_id break if not hosted_zone_id: raise NotInHostedZonesError(name) changes = ResourceRecordSets(conn, hosted_zone_id, comment) response = conn.get_all_rrsets(hosted_zone_id, type, name, maxitems=1) if response: rrset = response[0] change1 = changes.add_change("DELETE", name, type, rrset.ttl) for old_value in rrset.resource_records: change1.add_value(old_value) change2 = changes.add_change("CREATE", name, type, ttl) for new_value in values.split(','): change2.add_value(new_value) return changes.commit()
def start_rr_transaction(self): """ Creates a new Route53 ResourceRecordSets object that is used internally like a transaction of sorts. You may add or delete many resource records using a single set by calling the `add_record` and `delete_record` methods. Finish the transaction with `finish_rr_transaction` NOTE: Calling this method again before finishing will not finish an existing transaction or delete it. To cancel an existing transaction use the `cancel_rr_transaction`. """ if self._rr_txn is None: # Return a new ResourceRecordSets "transaction" self._rr_txn = ResourceRecordSets(self.conn, self.zone_id)