DNS Python 修改区域文件的脚本出现相对性错误并插入转义字符

DNS Python Script to Modify Zone File(s) getting relativity error and inserting escape characters

相对较新 python 和一般编程,但想自动化我正在为大量域工作的 DNS 迁移。

无耻地从 AgileTesting Blog.

偷了一些初始框架

脚本的当前状态

我可以在 soarr(respname) 函数中注释掉 rdata.rname = respname,所以我知道它在那里是特定的。不确定如何根据错误深入了解问题。

对于转义字符,我觉得很简单,但我脑子糊涂了,所以把它作为一个小问题。

#!/bin/python3
import re,sys
import dns.zone
from dns.exception import DNSException
from dns.rdataclass import *
from dns.rdatatype import *

script, filename, nameservers = sys.argv
sourcefile = open(filename,"r")

def soarr(respname):
        for (name, ttl, rdata) in zone.iterate_rdatas(SOA):
                serial = rdata.serial
                old_name = rdata.rname
                new_serial = serial + 1
                print ("Changing SOA serial from %d to %d" %(serial, new_serial))
                print ("Changing responsible name from %s to %s" %(old_name, respname))
                rdata.serial = new_serial
                rdata.rname = respname
                rdata.expire = 3600
                print (rdata.rname)

def nsrr(nameserver):
        NS_add = "@"
        target = dns.name.Name((nameserver,))
        print ("Adding record of type NS:", NS_add)
        rdataset = zone.find_rdataset(NS_add, rdtype=NS, create=True)
        rdata = dns.rdtypes.ANY.NS.NS(IN, NS, target)
        rdataset.add(rdata, ttl=3600)
        print (rdata)

def savefile(domain):
        print ("debug",domain)
        new_zone_file = "new.%s.hosts" % domain
        print ("Writing modified zone to file %s" % new_zone_file)
        zone.to_file(new_zone_file,domain)

for domainitem in sourcefile:
        domainitem = domainitem.rstrip()
        print ("Processing %s." % domainitem)
        zone_file = '%s.hosts' % domainitem
        zone = dns.zone.from_file(zone_file, domainitem)

# Updating the SOA record, responsible name, lowering TTL and incrementing serial of the zone file.
        soarr('systems.example.com')

# Adding name servers to the zone file.
        if nameservers == 'customer':
                nsrr('ns01.example.com')
        if nameservers == 'core':
                nsrr("ns01.example2.com")
        if nameservers == 'internal':
                nsrr("ns01.int.example2.com")

# Save the file as a new file.
        savefile(domainitem)

目的是从文件中循环访问域列表,打开适当的区域文件,操作区域并将更改保存到新命名的文件中。

保存失败错误。

Traceback (most recent call last):
  File "./zonefile.py", line 62, in <module>
    savefile(domainitem)
  File "./zonefile.py", line 36, in savefile
    zone.to_file(new_zone_file,domain)
  File "/usr/local/lib/python3.6/site-packages/dns/zone.py", line 531, in to_file
    relativize=relativize)
  File "/usr/local/lib/python3.6/site-packages/dns/node.py", line 51, in to_text
    s.write(rds.to_text(name, **kw))
  File "/usr/local/lib/python3.6/site-packages/dns/rdataset.py", line 218, in to_text
    **kw)))
  File "/usr/local/lib/python3.6/site-packages/dns/rdtypes/ANY/SOA.py", line 62, in to_text
    rname = self.rname.choose_relativity(origin, relativize)
AttributeError: 'str' object has no attribute 'choose_relativity'

如前所述,注释掉单行让我们保存文件。在保存的文件中,NS 条目显示转义字符。

@ 3600 IN NS ns01\.example\.com

您遇到的两个问题 - AttributeError 和转义字符 - 都是因为您没有正确创建 dns.name.Name

要从 str 创建 dns.name.Name,最好调用 dns.name.from_text()

示例:name = dns.name.from_text('example.com')

具体来说,在你的nsrr函数中,第二行应该改为

target = dns.name.from_text(nameserver)

并且在您的 soarr 函数中,您通过以下方式修复它:

rdata.rname = dns.name.from_text(respname)

这是我所做更改的副本(还有一些小的缩进更改)。

#!/bin/python3
import re
import sys
import dns.zone
from dns.exception import DNSException
from dns.rdataclass import *
from dns.rdatatype import *

script, filename, nameservers = sys.argv
sourcefile = open(filename,"r")

def soarr(respname):
    for (name, ttl, rdata) in zone.iterate_rdatas(SOA):
        serial = rdata.serial
        old_name = rdata.rname
        new_serial = serial + 1
        print ("Changing SOA serial from %d to %d" %(serial, new_serial))
        print ("Changing responsible name from %s to %s" %(old_name, respname))
        rdata.serial = new_serial
        rdata.rname = respname
        rdata.expire = 3600
        print (rdata.rname)

def nsrr(nameserver):
    NS_add = "@"
    target = dns.name.from_text(nameserver)
    print ("Adding record of type NS:", NS_add)
    rdataset = zone.find_rdataset(NS_add, rdtype=NS, create=True)
    rdata = dns.rdtypes.ANY.NS.NS(IN, NS, target)
    rdataset.add(rdata, ttl=3600)
    print (rdata)

def savefile(domain):
    print ("debug",domain)
    new_zone_file = "new.%s.hosts" % domain
    print ("Writing modified zone to file %s" % new_zone_file)
    zone.to_file(new_zone_file,domain)

for domainitem in sourcefile:
    domainitem = domainitem.rstrip()
    print ("Processing %s." % domainitem)
    zone_file = '%s.hosts' % domainitem
    zone = dns.zone.from_file(zone_file, domainitem)

    # Updating the SOA record, responsible name, lowering TTL and incrementing serial of the zone file.
    soarr(dns.name.from_text('systems.example.com'))

    # Adding name servers to the zone file.
    if nameservers == 'customer':
        nsrr('ns01.example.com')
    if nameservers == 'core':
        nsrr("ns01.example2.com")
    if nameservers == 'internal':
        nsrr("ns01.int.example2.com")

    # Save the file as a new file.
    savefile(domainitem)