使用b更新路由53中的DNS记录

2024-10-01 11:32:00 发布

您现在位置:Python中文网/ 问答频道 /正文

尝试使用boto更新R53中的dns记录时,出现以下错误:

Traceback (most recent call last):
File "testing.py", line 106, in <module>
updateDns(load_balancer_dns)
File "testing.py", line 102, in updateDns
change.commit()
File "/usr/lib/python2.6/site-packages/boto/route53/record.py", line 149, in commit
return self.connection.change_rrsets(self.hosted_zone_id, self.to_xml())
File "/usr/lib/python2.6/site-packages/boto/route53/connection.py", line 320, in change_rrsets
body)
boto.route53.exception.DNSServerError: DNSServerError: 505 HTTP Version Not Supported

以下是我用来更新dns条目的函数:

^{pr2}$

其他人之前也遇到过这样的问题吗?在


Tags: inpyselfdnslibusrlinesite
3条回答

我有一个类似的问题,所以作为一个“调试”练习,我做了一个

print zone_id

我注意到该对象是dict/JSON响应,因此我将代码改为

^{pr2}$

这似乎对我有用-我现在得到了一个403,但至少应该更容易解决。在

免责声明-Python新手,所以不确定这是否是正确的方法!在

仅供参考:

获取change_id,然后使用boto connection(conn)检查状态,直到它显示“INSYNC”

例如

 def updateDns(load_balancer_dns):
    r53 = boto.route53.connection.Route53Connection(aws_access_key_id=<access_key>,aws_secret_access_key=<secret_key>)
    zone_id = r53.get_hosted_zone_by_name(<domain_name>)
    print zone_id
    change = boto.route53.record.ResourceRecordSets(connection=r53,hosted_zone_id=zone_id)
    change.add_change_record("UPSERT", boto.route53.record.Record(name=<name>, type="CNAME", resource_records=load_balancer_dns, ttl=300))
    _changes = change.commit()

    change_id = _changes["ChangeResourceRecordSetsResponse"]["ChangeInfo"]["Id"].split("/")[-1]

    while True:
        status = r53.get_change(change_id)["GetChangeResponse"]["ChangeInfo"]["Status"]
        if status == "INSYNC": break
        sleep(10)

由于这并没有一个真正权威的答案,我只是拼凑了一个工作脚本:

#!/usr/bin/env python
# -*- coding: utf-8 -*-

from __future__ import absolute_import, print_function

from time import sleep

import boto


def main():
    """Entrypoint."""
    r53 = boto.connect_route53()
    zones = r53.get_all_hosted_zones()['ListHostedZonesResponse']['HostedZones']
    private_zone = find_private_zone('sub.mydomain.com.', zones)
    reverse_zone = find_private_zone('100.10.in-addr.arpa.', zones)

    upsert_record(r53, private_zone, 'dangus.sub.mydomain.com.', '127.0.0.1', 'A', wait=True)
    delete_record(r53, private_zone, 'dangus.sub.mydomain.com.', '127.0.0.1', 'A', wait=True)


def find_private_zone(name, zones):
    for zone in zones:
        if zone.get('Name') == name and zone.get('Config', {}).get('PrivateZone') in [True, 'true']:
            return zone

    return None


def find_record(r53, zone_id, name, record_type):
    records = r53.get_all_rrsets(zone_id)

    for record in records:
        if record.name == name and record.type == record_type:
            return record

    return None


def upsert_record(r53, zone, name, record, record_type, ttl=60, wait=False):
    print("Inserting record {}[{}] -> {}; TTL={}".format(name, record_type, record, ttl))
    recordset = boto.route53.record.ResourceRecordSets(connection=r53, hosted_zone_id=zone.get('Id').split('/')[-1])
    recordset.add_change_record('UPSERT', boto.route53.record.Record(
        name=name,
        type=record_type,
        resource_records=[record],
        ttl=ttl
    ))
    changeset = recordset.commit()

    change_id = changeset['ChangeResourceRecordSetsResponse']['ChangeInfo']['Id'].split('/')[-1]

    while wait:
        status = r53.get_change(change_id)['GetChangeResponse']['ChangeInfo']['Status']
        if status == 'INSYNC':
            break

        sleep(10)


def delete_record(r53, zone, name, record, record_type, wait=False):
    print("Deleting record {}[{}] -> {}".format(name, record_type, record))

    zone_id = zone.get('Id').split('/')[-1]
    record = find_record(r53, zone_id, name, record_type)

    if not record:
        print("No record exists.")
        return

    recordset = boto.route53.record.ResourceRecordSets(connection=r53, hosted_zone_id=zone.get('Id').split('/')[-1])
    recordset.add_change_record('DELETE', record)
    changeset = recordset.commit()

    change_id = changeset['ChangeResourceRecordSetsResponse']['ChangeInfo']['Id'].split('/')[-1]

    while wait:
        status = r53.get_change(change_id)['GetChangeResponse']['ChangeInfo']['Status']
        if status == 'INSYNC':
            break

        sleep(10)


if __name__ == "__main__":
    main()

不幸的是,我使用过的api都没有一个很好的route53实现,您最终不得不使用这些字典查找服务实际返回的XML。在

深渊:

  • 始终使用FQDN,这意味着每个记录都应以点结尾。在
  • 你不能只获取你要找的托管区域,你需要获取所有这些区域并搜索你要查找的区域(即:与给定名称匹配的私有区域)。在
  • 你必须从你的托管区域解析出ID。在
  • 您必须从变更集中解析出ID。在
  • 删除条目时,必须首先捕获记录的当前状态(如果它存在),然后将该值作为删除更改的一部分发送到路由53。在

这使得API的使用变得非常麻烦,但至少它解决了RFC-1925规则1:它可以工作。在

相关问题 更多 >