Python 3.x 用于修改区域文件的DNS Python脚本获取相对性错误并插入转义字符

Python 3.x 用于修改区域文件的DNS Python脚本获取相对性错误并插入转义字符,python-3.x,dnspython,Python 3.x,Dnspython,一般来说,对python和编程相对较新,但我想自动化我正在为大量域进行的DNS迁移 不知羞耻地窃取了一些最初的框架 在脚本的当前状态下 未能保存,但出现错误 在新名称服务器记录中插入转义字符 我可以在soarr(respname)函数中注释掉rdata.rname=respname,因此我知道它是特定的。不确定如何根据错误深入研究问题 对于逃避角色,我觉得这很简单,但我的大脑是糊状的,所以只是把它作为一个小问题 #!/bin/python3 import re,sys import dns.

一般来说,对python和编程相对较新,但我想自动化我正在为大量域进行的DNS迁移

不知羞耻地窃取了一些最初的框架

在脚本的当前状态下

  • 未能保存,但出现错误
  • 在新名称服务器记录中插入转义字符
我可以在
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'
回溯(最近一次呼叫最后一次):
文件“/zonefile.py”,第62行,在
保存文件(域项)
保存文件中第36行的文件“/zonefile.py”
zone.to_文件(新的_zone_文件,域)
文件“/usr/local/lib/python3.6/site packages/dns/zone.py”,第531行,在to_文件中
相对化=相对化)
文件“/usr/local/lib/python3.6/site packages/dns/node.py”,第51行,to_文本
s、 写入(rds.至_文本(名称,**kw))
文件“/usr/local/lib/python3.6/site packages/dns/rdataset.py”,第218行,文本为
**(千瓦)
文件“/usr/local/lib/python3.6/site packages/dns/rdtypes/ANY/SOA.py”,第62行,to_文本
rname=self.rname.选择相对论(起源,相对化)
AttributeError:“str”对象没有“choose_relativity”属性
如前所述,标记出单行,让我们保存文件。在保存的文件中,NS条目显示转义字符


NS ns01\.example\.com中的
@3600

您遇到的两个问题-属性错误和转义字符-都是因为您没有正确创建
dns.name.name
s

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

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

具体而言,在
nsrr
函数中,第二行应更改为

target=dns.name.from_text(名称服务器)
在您的
soarr
功能中,您可以使用以下方法修复它:

rdata.rname=dns.name.from_text(respname)
这是我所做更改的副本(还有一些小的缩进更改)

#/垃圾桶/蟒蛇3
进口稀土
导入系统
导入dns.zone
从dns.exception导入DNSExException
从dns.rdataclass导入*
从dns.rdatatype导入*
脚本,文件名,名称服务器=sys.argv
sourcefile=open(文件名为“r”)
def soarr(名称):
对于区域中的(名称、ttl、rdata)。迭代(SOA):
serial=rdata.serial
旧名称=rdata.rname
新_串行=串行+1
打印(“将SOA序列从%d更改为%d”%(序列,新的_序列))
打印(“将责任名称从%s更改为%s”%(旧名称,respname))
rdata.serial=新的\u序列
rdata.rname=respname
rdata.expire=3600
打印(rdata.rname)
def nsrr(名称服务器):
NS_add=“@”
target=dns.name.from_text(名称服务器)
打印(“添加NS:,NS_添加类型的记录”)
rdataset=zone.find\rdataset(NS\u add,rdtype=NS,create=True)
rdata=dns.rdtypes.ANY.NS.NS(IN,NS,target)
添加(rdata,ttl=3600)
打印(rdata)
def保存文件(域):
打印(“调试”,域)
new\u zone\u file=“new.%s.hosts”%domain
打印(“将修改的区域写入文件%s”%new\u zone\u file)
zone.to_文件(新的_zone_文件,域)
对于sourcefile中的domainitem:
domainitem=domainitem.rstrip()
打印(“正在处理%s.%domainitem)
区域_文件=“%s.hosts”%domainitem
zone=dns.zone.from_文件(zone_文件,domainitem)
#更新SOA记录、责任名称、降低TTL和增加区域文件的序列号。
soarr(dns.name.from_text('systems.example.com'))
#将名称服务器添加到区域文件。
如果名称服务器==“客户”:
nsrr('ns01.example.com')
如果名称服务器==“核心”:
nsrr(“ns01.example2.com”)
如果名称服务器==“内部”:
nsrr(“ns01.int.example2.com”)
#将文件另存为新文件。
保存文件(域项)

对于这样简单的问题,我们既高兴又恼火。我很感谢你花时间仔细检查这件事和你的解释。这将为我将来的迁移节省大量工作。没问题。很高兴这有帮助。我已经做了几次完全相同的事情了,哈哈