2

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

无耻地从AgileTesting 博客中窃取了一些初始框架。

在当前状态下,脚本

  • 无法保存并出现错误
  • 在新的名称服务器记录中插入转义字符

rdata.rname = respname我可以在函数中注释掉,soarr(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

4

1 回答 1

1

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

要从 a 创建 a dns.name.Namestr最好调用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)
于 2020-02-29T07:39:48.417 回答