Beispiel #1
0
def test_update_serial(zone):
    # basic
    with zone.writer() as txn:
        txn.update_serial()
    rdataset = zone.find_rdataset("@", "soa")
    assert rdataset[0].serial == 2
    # max
    with zone.writer() as txn:
        txn.update_serial(0xFFFFFFFF, False)
    rdataset = zone.find_rdataset("@", "soa")
    assert rdataset[0].serial == 0xFFFFFFFF
    # wraparound to 1
    with zone.writer() as txn:
        txn.update_serial()
    rdataset = zone.find_rdataset("@", "soa")
    assert rdataset[0].serial == 1
    # trying to set to zero sets to 1
    with zone.writer() as txn:
        txn.update_serial(0, False)
    rdataset = zone.find_rdataset("@", "soa")
    assert rdataset[0].serial == 1
    with pytest.raises(KeyError):
        with zone.writer() as txn:
            txn.update_serial(name=dns.name.from_text("unknown", None))
    with pytest.raises(ValueError):
        with zone.writer() as txn:
            txn.update_serial(-1)
    with pytest.raises(ValueError):
        with zone.writer() as txn:
            txn.update_serial(2**31)
Beispiel #2
0
def validate_zonemd(zone):
    """
    Validate the digest of the zone.

    @var zone: The zone object to validate.
    @type zone: dns.zone.Zone
    @rtype: (bool, str) tuple

    Returns a tuple of (success code, error message). The success code
    is True if the digest is correct, and False otherwise. The error
    message is "" if there is no error, otherwise a description of the
    problem.
    """
    # Get the SOA and ZONEMD records for the zone.
    zone_name = min(zone.keys())
    soa_rdataset = zone.get_rdataset(zone_name, dns.rdatatype.SOA)
    soa = soa_rdataset.items[0]
    #    zonemd = zone.find_rdataset(zone_name, ZONEMD_RTYPE).items[0]

    original_digests = {}
    for zonemd in zone.find_rdataset(zone_name, ZONEMD_RTYPE).items:
        # Verify that the SOA matches between the SOA and the ZONEMD.
        if soa.serial != zonemd.serial:
            err = ("SOA serial " + str(soa.serial) + " does not " +
                   "match ZONEMD serial " + str(zonemd.serial))
            return False, err

        # Save the original digest.
        if zonemd.algorithm in original_digests:
            err = ("Digest algorithm " + str(zonemd.algorithm) +
                   "used more than once")
            return False, err
        original_digests[zonemd.algorithm] = zonemd.digest

        # Put a placeholder in for the ZONEMD.
        if zonemd.algorithm in _EMPTY_DIGEST_BY_ALGORITHM:
            zonemd.digest = _EMPTY_DIGEST_BY_ALGORITHM[zonemd.algorithm]
        else:
            zonemd.digest = b'\0' * len(zonemd.digest)

    # Calculate the digest.
    digest = calculate_zonemd(zone)

    # Restore ZONEMD.
    for zonemd in zone.find_rdataset(zone_name, ZONEMD_RTYPE).items:
        zonemd.digest = original_digests[zonemd.algorithm]

    # Verify the digest in the zone matches the calculated value.
    if digest != original_digests[ZONEMD_DIGEST_SHA384]:
        zonemd_b2a = binascii.b2a_hex(original_digest[ZONEMD_DIGEST_SHA384])
        zonemd_hex = zonemd_b2a.decode()
        digest_hex = binascii.b2a_hex(digest).decode()
        err = ("ZONEMD digest " + zonemd_hex + " does not " +
               "match calculated digest " + digest_hex)
        return False, err

    # Everything matches, enjoy your zone.
    return True, ""
Beispiel #3
0
	def dnszone (account):
   	
		zone_file = "/etc/bind/db.local"
	
		domain = "localhost"
  
		try:

			
			zone = dns.zone.from_file(zone_file, domain)

	
			for (name, ttl, rdata) in zone.iterate_rdatas(SOA):	

				print rdata

				serial = rdata.serial

				new_serial = datetime.now().strftime("%Y%m%d%H%M%S")

    				print "Changing SOA serial from %s to %s" % (serial, new_serial)
							
				rdata.serial = int(new_serial)						
				rdata.mname = dns.name.Name(("ns1", "codeless-hosting", "co", ""))

				
				

			print "Adding record of type A:", account.domain

			NS_add = "@"

			target = dns.name.Name(("ns1", "codeless-hosting", "co", ""))

			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=86400)	
				
			rdataset = zone.find_rdataset("www", rdtype=A, create=True)

			rdata = dns.rdtypes.IN.A.A(IN, A, address="192.168.1.30")

			rdataset.add(rdata, ttl=86400)
	     
			new_zone_file = "/etc/bind/zones/db.%s" % account.domain
			
			zone.to_file(new_zone_file)

		
		except DNSException, e:

			print e
Beispiel #4
0
def update_zonemd(zone, zonemd_algorithm='sha384'):
    """
    Calculate the digest of the zone and update the ZONEMD record's
    digest value with that.

    The ZONEMD record must already be present, for example having been
    added by the add_zonemd() function.

    This function does *not* change the serial value of the ZONEMD
    record.

    @var zone: The zone object to update.
    @type zone: dns.zone.Zone
    @var zonemd_algorithm: The name of the algorithm to use, "sha384".
    @type zonemd_algorithm: str
    @rtype: dns.rdataset.Rdataset
    @raises ZoneDigestUnknownAlgorithm: zonemd_algorithm is unknown

    Returns the ZONEMD record added, as a ZONEMD object.
    """
    zone_name = min(zone.keys())
    digest = calculate_zonemd(zone, zonemd_algorithm)
    zonemd = zone.find_rdataset(zone_name, ZONEMD_RTYPE).items[0]
    zonemd.digest = digest
    return zonemd
Beispiel #5
0
 def check_record(self, key, ttype, value, domain):
     """Check if record already exist in domain
     AXFR used because resolver can also resolve addresses 
     from remote servers"""
     try:
         xfr = dns.query.xfr('127.0.0.1', domain ,keyring=self.keyring,
                   keyalgorithm=str(self.conf.bind_secret_algorithm).lower())
         zone = dns.zone.from_xfr(xfr)
         rdataset = zone.find_rdataset(key, rdtype=ttype)
         for rdata in rdataset:
             if ttype in ['NS','CNAME', 'PTR']:
                 address = rdata.target
             elif ttype == 'MX':
                 address = rdata.exchange
             else:
                 address = rdata.address
             if str(address).rstrip('.') == str(value):
                 return True
     except DNSException or FormError:
         self.log.info('Cannot make axfr query to domain %s' % domain)
     except KeyError:
         # record not found
         pass
     except AttributeError as e:
         self.log.error('BUG: Got attribute error on check_record')
         self.log.exception(e)
     return False
Beispiel #6
0
def modify_dns(new_IP):
    domain = "cap.com"
    zoneFile = "/etc/bind/zones/db.cap.com"

    zone = dns.zone.from_file(zoneFile, domain)

    change = "www"
    rdataset = zone.find_rdataset(change, rdtype='A')

    req_reload = False

    for rdata in rdataset:
        if rdata.address != new_IP:
            req_reload = True
            rdata.address = new_IP

    if req_reload:
        for (name, ttl, rdata) in zone.iterate_rdatas('SOA'):
            serial = rdata.serial + 1
            rdata.serial = serial

        zone.to_file(zoneFile)

        proc = Popen(["rndc", "reload", "cap.com"], stdout = PIPE, stderr = PIPE)
        out,err = proc.communicate()
        if err:
            print err
        else:
            pass
            #print "DNS zone modification complete"
    else:
        pass
Beispiel #7
0
 def get_serial_no(self, zone):
     """
     Obtain the serial number from the SOA of a zone
     """
     rdataset = zone.find_rdataset(zone.origin, 
                                     dns.rdatatype.from_text(RRTYPE_SOA))
     return rdataset.items[0].serial
Beispiel #8
0
    def generate(self, domains: Iterable[str], filename: str):
        ttl = 3600
        origin = "rpz.local"

        def read_header():
            with open(filename, "r") as f:
                for line in f:
                    if not line.startswith("@"):
                        break
                    yield line

        try:
            # Read "header" only since it's expensive to parse everything.
            zone = dns.zone.from_text("\n".join(read_header()), origin=origin)
        except (dns.exception.DNSException, IOError):
            zone = dns.zone.Zone(origin)

        existing_soa_set = zone.get_rdataset("@", "SOA")
        zone.nodes.clear()

        soa_set = zone.find_rdataset("@", "SOA", create=True)
        if existing_soa_set is None:
            soa_set.ttl = 3600
            soa_set.add(
                dns.rdata.from_text("IN", "SOA",
                                    "@ hostmaster 0 86400 7200 2592000 86400"))
            logging.info("creating zone from scratch")
        else:
            soa_set.update(existing_soa_set)
            # Increment serial.
            serial = soa_set[0].serial + 1
            soa_set.add(soa_set[0].replace(serial=serial))
            logging.info("parsed existing header, new serial is %d", serial)

        in_ns = zone.find_rdataset("@", "NS", create=True)
        in_ns.ttl = ttl
        in_ns.add(dns.rdata.from_text("IN", "NS", "LOCALHOST."))

        in_cname_dot = dns.rdataset.from_text("IN", "CNAME", ttl, ".")
        for domain in domains:
            zone.find_node(domain, create=True).replace_rdataset(in_cname_dot)

        zone.to_file(filename, sorted=True)
        logging.info("block list has %d domains", len(zone.nodes) - 1)
Beispiel #9
0
    def _increment_serial(self, zone):
        """Increment the serial number in the zone.
        
        Arguments:
            zone -- a dnspython.zone.Zone object
        """

        soa_rd = zone.find_rdataset(zone.origin, "SOA")
        soa = soa_rd.items[0]
        soa.serial += 1
Beispiel #10
0
def generateOneCountry(category, zone, hosts):
    for h in hosts:
        domainname = domainTemplateToName(category.GeoDNSDomain, h.country)
        n = dns.name.from_text(domainname)

        try:
            ips = [IPy.IP(h.name)]
        except ValueError:
            ips = name_to_ips(h.name)
        except:
            continue

        for ip in ips:
            if ip.version() == 4:
                rdatasetA    = zone.find_rdataset(n, rdtype=A, create=True)
                rdata = dns.rdtypes.IN.A.A(IN, A, ip.strNormal())
                rdatasetA.add(rdata, ttl=default_ttl)
            elif ip.version() == 6:
                rdatasetAAAA = zone.find_rdataset(n, rdtype=AAAA, create=True)
                rdata = dns.rdtypes.IN.AAAA.AAAA(IN, AAAA, ip.strNormal())
                rdatasetAAAA.add(rdata, ttl=default_ttl)
            else:
                continue
Beispiel #11
0
def validate_zonemd(zone):
    """
    Validate the digest of the zone.

    @var zone: The zone object to validate.
    @type zone: dns.zone.Zone
    @rtype: (bool, str) tuple

    Returns a tuple of (success code, error message). The success code
    is True if the digest is correct, and False otherwise. The error
    message is "" if there is no error, otherwise a description of the
    problem.
    """
    # Get the SOA and ZONEMD records for the zone.
    zone_name = min(zone.keys())
    soa_rdataset = zone.get_rdataset(zone_name, dns.rdatatype.SOA)
    soa = soa_rdataset.items[0]
    zonemd = zone.find_rdataset(zone_name, ZONEMD_RTYPE).items[0]

    # Verify that the SOA matches between the SOA and the ZONEMD.
    if soa.serial != zonemd.serial:
        err = ("SOA serial " + str(soa.serial) + " does not " +
               "match ZONEMD serial " + str(zonemd.serial))
        return False, err

    # Verify that we understand the digest algorithm.
    if zonemd.algorithm not in _EMPTY_DIGEST_BY_ALGORITHM:
        err = "Unknown digest algorithm " + str(zonemd.algorithm)
        return False, err

    # Put a placeholder in for the ZONEMD.
    original_digest = zonemd.digest
    zonemd.digest = _EMPTY_DIGEST_BY_ALGORITHM[zonemd.algorithm]

    # Calculate the digest and restore ZONEMD.
    digest = calculate_zonemd(zone, zonemd.algorithm)
    zonemd.digest = original_digest

    # Verify the digest in the zone matches the calculated value.
    if digest != zonemd.digest:
        zonemd_hex = binascii.b2a_hex(zonemd.digest).decode()
        digest_hex = binascii.b2a_hex(digest).decode()
        err = ("ZONEMD digest " + zonemd_hex + " does not " +
               "match calculated digest " + digest_hex)
        return False, err

    # Everything matches, enjoy your zone.
    return True, ""
Beispiel #12
0
def update_domain(domain, zonefile, secret):
    '''
    Updates the given domain with the new ACME secret.
    '''
    zone = dns.zone.from_file(zonefile, domain)

    # updata soa serial
    for (_, _, rdata) in zone.iterate_rdatas(SOA):
        rdata.serial += 1

    # update the acme challenge
    acme_record = zone.find_rdataset('_acme-challenge', rdtype=TXT)
    for rdata in acme_record:
        rdata.strings = [secret.encode("utf8")]

    zone.to_file(zonefile)
Beispiel #13
0
def make_xfr(zone):
    q = dns.message.make_query(zone.origin, 'AXFR')
    msg = dns.message.make_response(q)
    if zone.relativize:
        msg.origin = zone.origin
        soa_name = dns.name.empty
    else:
        soa_name = zone.origin
    soa = zone.find_rdataset(soa_name, 'SOA')
    add_rdataset(msg, soa_name, soa)
    for (name, rds) in zone.iterate_rdatasets():
        if rds.rdtype == dns.rdatatype.SOA:
            continue
        add_rdataset(msg, name, rds)
    add_rdataset(msg, soa_name, soa)
    return [msg]
Beispiel #14
0
def setup_serial(zone):
  serial=0
  fn=os.environ.get("ZONE_UTIL_SERIAL_FILE") or "/var/bind/serial.txt"

  if os.path.isfile(fn):
    fh=open(fn,'r')
    serial=int(fh.readline())
    fh.close()

  soa=zone.find_rdataset(zone.origin,'SOA')[0]
  serial+=1
  soa.serial=serial

  fh=open(fn,'w')
  fh.write(str(serial) +"\n")
  fh.close()

  return zone
Beispiel #15
0
def setup_serial(zone):
    serial = 0
    fn = os.environ.get("ZONE_UTIL_SERIAL_FILE") or "/var/bind/serial.txt"

    if os.path.isfile(fn):
        fh = open(fn, 'r')
        serial = int(fh.readline())
        fh.close()

    soa = zone.find_rdataset(zone.origin, 'SOA')[0]
    serial += 1
    soa.serial = serial

    fh = open(fn, 'w')
    fh.write(str(serial) + "\n")
    fh.close()

    return zone
Beispiel #16
0
def append(ip_adres=None, hostname=None, UUID=None):
    if mongo.db.users.find_one({'token': UUID}):
        zonefile = '/etc/bind/db.example.com'
        zone = dns.zone.from_file(zonefile, os.path.basename(zonefile))
        rdataset = zone.find_rdataset(hostname, dns.rdatatype.A, create=True)
        rdata = dns.rdtypes.IN.A.A(dns.rdataclass.IN, dns.rdatatype.A,
                                   ip_adres)
        rdataset.add(rdata, 86400)
        zone.to_file(zonefile)
        subprocess.call(["sudo", "rndc", "reload"])
        filter = {'username': session['username']}
        update = {"$push": {"fqdns": hostname}}
        mongo.db.users.update_one(filter, update)
        return {
            "message":
            "new A-record with ip {} and hostname {} inserted".format(
                ip_adres, hostname)
        }
    else:
        return {"message": "not authorized"}
Beispiel #17
0
def generate_zone_file(origin):
    """Generates a zone file.
    
    Accepts the zone origin as string (no trailing dot).
     
    Returns the contents of a zone file that contains all the resource records
    associated with the domain with the provided origin.
    
    """
    Domain = get_model('powerdns_manager', 'Domain')
    Record = get_model('powerdns_manager', 'Record')
    
    the_domain = Domain.objects.get(name__exact=origin)
    the_rrs = Record.objects.filter(domain=the_domain).order_by('-type')
    
    # Generate the zone file
    
    origin = Name((origin.rstrip('.') + '.').split('.'))
    
    # Create an empty dns.zone object.
    # We set check_origin=False because the zone contains no records.
    zone = dns.zone.from_text('', origin=origin, relativize=False, check_origin=False)
    
    rdclass = dns.rdataclass._by_text.get('IN')
    
    for rr in the_rrs:
        
        # Add trailing dot to rr.name
        record_name = rr.name.rstrip('.') + '.'
        
        if rr.type == 'SOA':
            # Add SOA Resource Record
            
            # SOA content:  primary hostmaster serial refresh retry expire default_ttl
            bits = rr.content.split()
            # Primary nameserver of SOA record
            primary = bits[0].rstrip('.') + '.'
            mname = Name(primary.split('.'))
            # Responsible hostmaster from SOA record
            hostmaster = bits[1].rstrip('.') + '.'
            rname = Name(hostmaster.split('.'))
            
            rdtype = dns.rdatatype._by_text.get('SOA')
            rdataset = zone.find_rdataset(record_name, rdtype=rdtype, create=True)
            rdata = dns.rdtypes.ANY.SOA.SOA(rdclass, rdtype,
                mname = mname,
                rname = rname,
                serial = int(bits[2]),
                refresh = int(bits[3]),
                retry = int(bits[4]),
                expire = int(bits[5]),
                minimum = int(bits[6])
            )
            rdataset.add(rdata, ttl=int(rr.ttl))
        
        elif rr.type == 'NS':
            # Add NS Resource Record
            rdtype = dns.rdatatype._by_text.get('NS')
            rdataset = zone.find_rdataset(record_name, rdtype=rdtype, create=True)
            rdata = dns.rdtypes.ANY.NS.NS(rdclass, rdtype,
                target = Name((rr.content.rstrip('.') + '.').split('.'))
            )
            rdataset.add(rdata, ttl=int(rr.ttl))
        
        elif rr.type == 'MX':
            # Add MX Resource Record
            rdtype = dns.rdatatype._by_text.get('MX')
            rdataset = zone.find_rdataset(record_name, rdtype=rdtype, create=True)
            rdata = dns.rdtypes.ANY.MX.MX(rdclass, rdtype,
                preference = int(rr.prio),
                exchange = Name((rr.content.rstrip('.') + '.').split('.'))
            )
            rdataset.add(rdata, ttl=int(rr.ttl))
        
        elif rr.type == 'TXT':
            # Add TXT Resource Record
            rdtype = dns.rdatatype._by_text.get('TXT')
            rdataset = zone.find_rdataset(record_name, rdtype=rdtype, create=True)
            rdata = dns.rdtypes.ANY.TXT.TXT(rdclass, rdtype,
                strings = [rr.content.strip('"')]
            )
            rdataset.add(rdata, ttl=int(rr.ttl))
        
        elif rr.type == 'CNAME':
            # Add CNAME Resource Record
            rdtype = dns.rdatatype._by_text.get('CNAME')
            rdataset = zone.find_rdataset(record_name, rdtype=rdtype, create=True)
            rdata = dns.rdtypes.ANY.CNAME.CNAME(rdclass, rdtype,
                target = Name((rr.content.rstrip('.') + '.').split('.'))
            )
            rdataset.add(rdata, ttl=int(rr.ttl))
        
        elif rr.type == 'A':
            # Add A Resource Record
            rdtype = dns.rdatatype._by_text.get('A')
            rdataset = zone.find_rdataset(record_name, rdtype=rdtype, create=True)
            rdata = dns.rdtypes.IN.A.A(rdclass, rdtype,
                address = rr.content
            )
            rdataset.add(rdata, ttl=int(rr.ttl))
        
        elif rr.type == 'AAAA':
            # Add AAAA Resource Record
            rdtype = dns.rdatatype._by_text.get('AAAA')
            rdataset = zone.find_rdataset(record_name, rdtype=rdtype, create=True)
            rdata = dns.rdtypes.IN.AAAA.AAAA(rdclass, rdtype,
                address = rr.content
            )
            rdataset.add(rdata, ttl=int(rr.ttl))
        
        elif rr.type == 'SPF':
            # Add SPF Resource Record
            rdtype = dns.rdatatype._by_text.get('SPF')
            rdataset = zone.find_rdataset(record_name, rdtype=rdtype, create=True)
            rdata = dns.rdtypes.ANY.SPF.SPF(rdclass, rdtype,
                strings = [rr.content.strip('"')]
            )
            rdataset.add(rdata, ttl=int(rr.ttl))
        
        elif rr.type == 'PTR':
            # Add PTR Resource Record
            rdtype = dns.rdatatype._by_text.get('PTR')
            rdataset = zone.find_rdataset(record_name, rdtype=rdtype, create=True)
            rdata = dns.rdtypes.ANY.PTR.PTR(rdclass, rdtype,
                target = Name((rr.content.rstrip('.') + '.').split('.'))
            )
            rdataset.add(rdata, ttl=int(rr.ttl))
        
        elif rr.type == 'SRV':
            # Add SRV Resource Record
            
            # weight port target
            weight, port, target = rr.content.split()
            
            rdtype = dns.rdatatype._by_text.get('SRV')
            rdataset = zone.find_rdataset(record_name, rdtype=rdtype, create=True)
            rdata = dns.rdtypes.IN.SRV.SRV(rdclass, rdtype,
                priority = int(rr.prio),
                weight = int(weight),
                port = int(port),
                target = Name((target.rstrip('.') + '.').split('.'))
            )
            rdataset.add(rdata, ttl=int(rr.ttl))
            
    
    # Export text (from the source code of http://www.dnspython.org/docs/1.10.0/html/dns.zone.Zone-class.html#to_file)
    EOL = '\n'
    f = StringIO.StringIO()
    f.write('$ORIGIN %s%s' % (origin, EOL))
    zone.to_file(f, sorted=True, relativize=False, nl=EOL)
    data = f.getvalue()
    f.close()
    return data
Beispiel #18
0
        """

        # Define the response of a successful execution of the function
        http_status = 200
        prog_status = 0
        explanation = "Successfully created specified SRV record (Service: {} Port: {} A Record: {})".format(service_name, service_port, A_record)

        domain = "simplicify.com"
        zone_file = "/etc/bind/zones/db.%s" % domain
        new_zone_file = "new.db.%s" % domain
        try:
            zone = dns.zone.from_file(zone_file, domain)
        except DNSException, e:
            print e.__class__, e
        n = dns.name.from_text(A_record)
        rdataset = zone.find_rdataset(service_name, rdtype='SRV', create=True)
        rdata = dns.rdtypes.IN.SRV.SRV(IN,SRV,0,0,service_port,target=n)
        rdataset.add(rdata, ttl=86400)
        print str(rdataset)
        print str(rdata)
        try:
            zone.to_file(new_zone_file)
        except:
                explanation = "An unknown error occurred adding the specified SRV record (Service: {} Port: {} A Record: {})".format(service_name, service_port, A_record)
                status = 500
                return [ 1, status, explanation, "" ]

        payload = ""
        returns = [ prog_status, http_status, explanation, payload ]

        return returns
Beispiel #19
0
def generate_zone_file(origin):
    """Generates a zone file.
    
    Accepts the zone origin as string (no trailing dot).
     
    Returns the contents of a zone file that contains all the resource records
    associated with the domain with the provided origin.
    
    """
    Domain = cache.get_model('powerdns_manager', 'Domain')
    Record = cache.get_model('powerdns_manager', 'Record')
    
    the_domain = Domain.objects.get(name__exact=origin)
    the_rrs = Record.objects.filter(domain=the_domain).order_by('-type')
    
    # Generate the zone file
    
    origin = Name((origin.rstrip('.') + '.').split('.'))
    
    # Create an empty dns.zone object.
    # We set check_origin=False because the zone contains no records.
    zone = dns.zone.from_text('', origin=origin, relativize=False, check_origin=False)
    
    rdclass = dns.rdataclass._by_text.get('IN')
    
    for rr in the_rrs:
        
        # Add trailing dot to rr.name
        record_name = rr.name.rstrip('.') + '.'
        
        if rr.type == 'SOA':
            # Add SOA Resource Record
            
            # SOA content:  primary hostmaster serial refresh retry expire default_ttl
            bits = rr.content.split()
            # Primary nameserver of SOA record
            primary = bits[0].rstrip('.') + '.'
            mname = Name(primary.split('.'))
            # Responsible hostmaster from SOA record
            hostmaster = bits[1].rstrip('.') + '.'
            rname = Name(hostmaster.split('.'))
            
            rdtype = dns.rdatatype._by_text.get('SOA')
            rdataset = zone.find_rdataset(record_name, rdtype=rdtype, create=True)
            rdata = dns.rdtypes.ANY.SOA.SOA(rdclass, rdtype,
                mname = mname,
                rname = rname,
                serial = int(bits[2]),
                refresh = int(bits[3]),
                retry = int(bits[4]),
                expire = int(bits[5]),
                minimum = int(bits[6])
            )
            rdataset.add(rdata, ttl=int(rr.ttl))
        
        elif rr.type == 'NS':
            # Add NS Resource Record
            rdtype = dns.rdatatype._by_text.get('NS')
            rdataset = zone.find_rdataset(record_name, rdtype=rdtype, create=True)
            rdata = dns.rdtypes.ANY.NS.NS(rdclass, rdtype,
                target = Name((rr.content.rstrip('.') + '.').split('.'))
            )
            rdataset.add(rdata, ttl=int(rr.ttl))
        
        elif rr.type == 'MX':
            # Add MX Resource Record
            rdtype = dns.rdatatype._by_text.get('MX')
            rdataset = zone.find_rdataset(record_name, rdtype=rdtype, create=True)
            rdata = dns.rdtypes.ANY.MX.MX(rdclass, rdtype,
                preference = int(rr.prio),
                exchange = Name((rr.content.rstrip('.') + '.').split('.'))
            )
            rdataset.add(rdata, ttl=int(rr.ttl))
        
        elif rr.type == 'TXT':
            # Add TXT Resource Record
            rdtype = dns.rdatatype._by_text.get('TXT')
            rdataset = zone.find_rdataset(record_name, rdtype=rdtype, create=True)
            rdata = dns.rdtypes.ANY.TXT.TXT(rdclass, rdtype,
                strings = rr.content.split(';')
            )
            rdataset.add(rdata, ttl=int(rr.ttl))
        
        elif rr.type == 'CNAME':
            # Add CNAME Resource Record
            rdtype = dns.rdatatype._by_text.get('CNAME')
            rdataset = zone.find_rdataset(record_name, rdtype=rdtype, create=True)
            rdata = dns.rdtypes.ANY.CNAME.CNAME(rdclass, rdtype,
                target = Name((rr.content.rstrip('.') + '.').split('.'))
            )
            rdataset.add(rdata, ttl=int(rr.ttl))
        
        elif rr.type == 'A':
            # Add A Resource Record
            rdtype = dns.rdatatype._by_text.get('A')
            rdataset = zone.find_rdataset(record_name, rdtype=rdtype, create=True)
            rdata = dns.rdtypes.IN.A.A(rdclass, rdtype,
                address = rr.content
            )
            rdataset.add(rdata, ttl=int(rr.ttl))
        
        elif rr.type == 'AAAA':
            # Add AAAA Resource Record
            rdtype = dns.rdatatype._by_text.get('AAAA')
            rdataset = zone.find_rdataset(record_name, rdtype=rdtype, create=True)
            rdata = dns.rdtypes.IN.AAAA.AAAA(rdclass, rdtype,
                address = rr.content
            )
            rdataset.add(rdata, ttl=int(rr.ttl))
        
        elif rr.type == 'SPF':
            # Add SPF Resource Record
            rdtype = dns.rdatatype._by_text.get('SPF')
            rdataset = zone.find_rdataset(record_name, rdtype=rdtype, create=True)
            rdata = dns.rdtypes.ANY.SPF.SPF(rdclass, rdtype,
                strings = rr.content.split(';')
            )
            rdataset.add(rdata, ttl=int(rr.ttl))
        
        elif rr.type == 'PTR':
            # Add PTR Resource Record
            rdtype = dns.rdatatype._by_text.get('PTR')
            rdataset = zone.find_rdataset(record_name, rdtype=rdtype, create=True)
            rdata = dns.rdtypes.ANY.PTR.PTR(rdclass, rdtype,
                target = Name((rr.content.rstrip('.') + '.').split('.'))
            )
            rdataset.add(rdata, ttl=int(rr.ttl))
        
        elif rr.type == 'SRV':
            # Add SRV Resource Record
            
            # weight port target
            weight, port, target = rr.content.split()
            
            rdtype = dns.rdatatype._by_text.get('SRV')
            rdataset = zone.find_rdataset(record_name, rdtype=rdtype, create=True)
            rdata = dns.rdtypes.IN.SRV.SRV(rdclass, rdtype,
                priority = int(rr.prio),
                weight = int(weight),
                port = int(port),
                target = Name((target.rstrip('.') + '.').split('.'))
            )
            rdataset.add(rdata, ttl=int(rr.ttl))
            
    
    # Export text (from the source code of http://www.dnspython.org/docs/1.10.0/html/dns.zone.Zone-class.html#to_file)
    EOL = '\r\n'
    f = StringIO.StringIO()
    f.write('$ORIGIN %s%s' % (origin, EOL))
    zone.to_file(f, sorted=True, relativize=False, nl=EOL)
    data = f.getvalue()
    f.close()
    return data
Beispiel #20
0
    def update_zone(self,
                    zone_name,
                    zi,
                    db_soa_serial=None,
                    candidate_soa_serial=None,
                    force_soa_serial_update=False,
                    wrap_serial_next_time=False,
                    date_stamp=None,
                    nsec3_seed=False,
                    clear_dnskey=False,
                    clear_nsec3=False):
        """
        Use dnspython to update a Zone in the DNS server

        Use wrap_serial_next_time to 'fix' SOA serial numbers grossly not 
        in the operations format YYYYMMDDnn. date is a datetime object in 
        localtime.
        """
        # Read in via AXFR zone for comparison purposes
        try:
            zone, dnskey_flag, nsec3param_flag = self.read_zone(zone_name)
            update_info = {
                'dnskey_flag': dnskey_flag,
                'nsec3param_flag': nsec3param_flag
            }
        except NoSuchZoneOnServerError as exc:
            msg = str(exc)
            #return (RCODE_FATAL, msg, None, None)
            # Send RESET as server not configured yet.
            return (RCODE_RESET, msg, None, None)

        except (dns.query.UnexpectedSource, dns.query.BadResponse) as exc:
            msg = ("Zone '%s', - server %s not operating correctly." %
                   (zone_name, server.server_name))
            return (RCODE_FATAL, msg, None, None)

        except (IOError, OSError) as exc:
            if exc.errno in (errno.EACCES, errno.EPERM, errno.ECONNREFUSED,
                             errno.ENETUNREACH, errno.ETIMEDOUT):
                msg = ("Zone '%s' - server %s:%s not available - %s" %
                       (zone_name, self.server, self.port, exc.strerror))
                return (RCODE_ERROR, msg, None, None)
            msg = ("Zone '%s' - server %s:%s, fatal error %s." %
                   (zone_name, self.server, self.port, exc.strerror))
            return (RCODE_FATAL, msg, None, None)

        # Get current SOA record for zone to include as prerequiste in update
        # Makes update transaction idempotent
        current_soa_rr = zone.find_rdataset(zone.origin, RRTYPE_SOA).items[0]

        update_soa_serial_flag = False
        curr_serial_no = self.get_serial_no(zone)
        # In case of a DR failover, our DB can have a more recent serial number
        # than in name server
        try:
            new_serial_no = new_soa_serial_no(
                curr_serial_no,
                zone_name,
                db_soa_serial=db_soa_serial,
                candidate=candidate_soa_serial,
                wrap_serial_next_time=wrap_serial_next_time,
                date_stamp=date_stamp)
        except SOASerialError as exc:
            msg = str(exc)
            if (not sys.stdin.isatty()):
                log_critical(msg)
            return (RCODE_FATAL, msg, None, None)
        if wrap_serial_next_time or force_soa_serial_update:
            # Apply serial number to SOA record.
            zi.update_soa_serial(new_serial_no)
        else:
            # An increment should only be performed after difference
            update_soa_serial_flag = True

        # Compare server_zone with zi.rrs
        # Find additions and deletions
        del_rrs = [
            rr for rr in zone.iterate_rdatas()
            if rr not in zi.iterate_dnspython_rrs()
        ]
        add_rrs = [
            rr for rr in zi.iterate_dnspython_rrs()
            if rr not in zone.iterate_rdatas()
        ]
        # Check if DNSSEC settings need to be changed
        do_clear_nsec3 = clear_nsec3 and nsec3param_flag
        do_clear_dnskey = clear_dnskey and dnskey_flag
        do_nsec3_seed = nsec3_seed and not nsec3param_flag

        if (not del_rrs and not add_rrs and not do_clear_nsec3
                and not do_clear_dnskey and not do_nsec3_seed):
            msg = ("Domain '%s' not updated as no change detected" %
                   (zone_name))
            return (RCODE_NOCHANGE, msg, curr_serial_no, update_info)

        # Incremental update of SOA serial number
        soa_rdtype = dns.rdatatype.from_text(RRTYPE_SOA)
        if update_soa_serial_flag:
            # Apply serial number to SOA record.
            zi.update_soa_serial(new_serial_no)
            # recalculate add_rrs - got to be done or else updates will be
            # missed
            add_rrs = [
                rr for rr in zi.iterate_dnspython_rrs()
                if rr not in zone.iterate_rdatas()
            ]

        # Groom updates for DynDNS update perculiarities

        # SOA can never be deleted RFC 2136 Section 3.4.2.3 and 3.4.2.4
        # so skip this.
        del_rrs = [rr for rr in del_rrs if (rr[2].rdtype != soa_rdtype)]

        # Can never delete the last NS on the root of a zone,
        # so pre add all '@' NS records (RFC 2136 Sec
        # 3.4.2.4)
        tl_label = dns.name.from_text('@', origin=dns.name.empty)
        ns_rdtype = dns.rdatatype.from_text(RRTYPE_NS)
        pre_add_rrs = [
            rr for rr in add_rrs
            if (rr[0] == tl_label and rr[2].rdtype == ns_rdtype)
        ]
        tl_ns_rdata = [rr[2] for rr in pre_add_rrs]
        add_rrs = [rr for rr in add_rrs if rr not in pre_add_rrs]
        # Remove '@' NS delete from del_rrs if record in pre_add_rrs
        # ie, we are just doing a TTL update!
        del_rrs = [
            rr for rr in del_rrs
            if (not (rr[0] == tl_label and rr[2] in tl_ns_rdata))
        ]

        # CNAMEs can only be added to vacant nodes, or totally replace
        # RRSET on a node RFC 2136 Section 3.4.2.2
        # Choose to enforce this at zi API level.

        # DNSSEC processing - prepare NSEC3PARM rdata
        if do_nsec3_seed:
            rn = random.getrandbits(int(settings['nsec3_salt_bit_length']))
            hash_alg = settings['nsec3_hash_algorithm']
            flags = settings['nsec3_flags']
            iterations = settings['nsec3_iterations']
            nsec3param_rdata = ("%s %s %s %016x" %
                                (hash_alg, flags, iterations, rn))
            # Test rn as random can produce garbage sometimes...
            rdata_list = nsec3param_rdata.split()
            try:
                # This is the piece of code where dnspython blows up...
                stuff = bytes.fromhex(rdata_list[-1])
            except Exception:
                msg = ("Failed to seed NSEC3 salt - SM reset required")
                return (RCODE_RESET, msg, None, update_info)

        # Prepare dnspython tsigkeyring
        keyring = dns.tsigkeyring.from_text(
            {self.key_name: self.tsig_key['secret']})
        if (self.tsig_key['algorithm'] == 'hmac-md5'):
            key_algorithm = dns.tsig.HMAC_MD5
        else:
            key_algorithm = dns.name.from_text(self.tsig_key['algorithm'])

        # Create update
        # We have to use absolute FQDNs on LHS  and RHS to make sure updates
        # to NS etc happen
        # While doing this also handle wee things for DNSSEC processing
        origin = dns.name.from_text(zone_name)
        update = dns.update.Update(origin,
                                   keyring=keyring,
                                   keyname=self.key_name,
                                   keyalgorithm=key_algorithm)
        update.present(origin, current_soa_rr)
        for rr in pre_add_rrs:
            update.add(rr[0], rr[1], rr[2])
        for rr in del_rrs:
            update.delete(rr[0], rr[2])
        # Add DNSSEC clearance stuff to end of delete section of update
        if do_clear_nsec3:
            update.delete(origin, RRTYPE_NSEC3PARAM)
        if do_clear_dnskey:
            update.delete(origin, RRTYPE_DNSKEY)
        for rr in add_rrs:
            update.add(rr[0], rr[1], rr[2])
        # NSEC3PARAM seeding
        if do_nsec3_seed:
            update.add(origin, '0', RRTYPE_NSEC3PARAM, nsec3param_rdata)

        # Do dee TING!
        response = dns.query.tcp(update, self.server, port=self.port)

        # Process reply
        rcode = response.rcode()
        rcode_text = dns.rcode.to_text(response.rcode())
        success_rcodes = (dns.rcode.NOERROR)
        if (rcode in self.success_rcodes):
            msg = ("Update '%s' to domain '%s' succeeded" %
                   (new_serial_no, zone_name))
            return (RCODE_OK, msg, new_serial_no, update_info)
        elif (rcode in self.retry_rcodes):
            msg = ("Update '%s' to domain '%s' failed: %s - will retry" %
                   (new_serial_no, zone_name, rcode_text))
            return (RCODE_ERROR, msg, None, update_info)
        elif (rcode in self.reset_rcodes):
            msg = (
                "Update '%s' to domain '%s' failed: %s - SM reset required" %
                (new_serial_no, zone_name, rcode_text))
            return (RCODE_RESET, msg, None, update_info)
        elif (rcode in self.fatal_rcodes):
            msg = ("Update '%s' to domain '%s' permanently failed: %s" %
                   (new_serial_no, zone_name, rcode_text))
            return (RCODE_FATAL, msg, None, update_info)
        else:
            msg = ("Update '%s' to domain '%s' permanently failed: '%s'"
                   " - unknown response" %
                   (new_serial_no, zone_name, response.rcode()))
            return (RCODE_FATAL, msg, None, update_info)
Beispiel #21
0
    print "Origen de la zona:", zone.origin

    for (name, ttl, rdata) in zone.iterate_rdatas(SOA):
        serial = rdata.serial
        new_serial = serial + 1
        print "Cambiando serial del SOA de %d a %d" % (serial, new_serial)
        rdata.serial = new_serial

    node_delete = "www2"
    print "Eliminando nodo", node_delete
    zone.delete_node(node_delete)

    A_change = "mail"
    new_IP = "192.168.2.100"
    print "Cambiando IPV4 del nodo", A_change, "al", new_IP
    rdataset = zone.find_rdataset(A_change, rdtype=A)
    for rdata in rdataset:
        rdata.address = new_IP

    rdataset = zone.find_rdataset("@", rdtype=NS)
    new_ttl = rdataset.ttl / 2
    print "Cambiando el TTL de todos los NS a", new_ttl
    rdataset.ttl = new_ttl

    A_add = "www3"
    print "Añadir nuevo nodo www3:", A_add
    rdataset = zone.find_rdataset(A_add, rdtype=A, create=True)
    rdata = dns.rdtypes.IN.A.A(IN, A, address="192.168.10.30")
    rdataset.add(rdata, ttl=86400)

    new_zone_file = "new.%s" % domain
Beispiel #22
0
    def update_zone(self, zone_name, zi, db_soa_serial=None, 
            candidate_soa_serial=None,
            force_soa_serial_update=False, wrap_serial_next_time=False,
            date_stamp=None, nsec3_seed=False, clear_dnskey=False,
            clear_nsec3=False):
        """
        Use dnspython to update a Zone in the DNS server

        Use wrap_serial_next_time to 'fix' SOA serial numbers grossly not 
        in the operations format YYYYMMDDnn. date is a datetime object in 
        localtime.
        """
        # Read in via AXFR zone for comparison purposes
        try:
            zone, dnskey_flag, nsec3param_flag = self.read_zone(zone_name)
            update_info = {'dnskey_flag': dnskey_flag, 
                            'nsec3param_flag': nsec3param_flag}
        except NoSuchZoneOnServerError as exc:
            msg = str(exc)
            #return (RCODE_FATAL, msg, None, None)
            # Send RESET as server not configured yet.
            return (RCODE_RESET, msg, None, None)

        except (dns.query.UnexpectedSource, dns.query.BadResponse) as exc:
            msg = ("Zone '%s', - server %s not operating correctly." 
                        % (zone_name, server.server_name))
            return (RCODE_FATAL, msg, None, None)
        
        except (IOError, OSError) as exc:
            if exc.errno in (errno.EACCES, errno.EPERM, errno.ECONNREFUSED, 
                    errno.ENETUNREACH, errno.ETIMEDOUT):
                msg = ("Zone '%s' - server %s:%s not available - %s"
                        % (zone_name, self.server, self.port, exc.strerror))
                return (RCODE_ERROR, msg, None, None)
            msg = ("Zone '%s' - server %s:%s, fatal error %s."
                   % (zone_name, self.server, self.port, exc.strerror))
            return (RCODE_FATAL, msg, None, None)


        # Get current SOA record for zone to include as prerequiste in update
        # Makes update transaction idempotent
        current_soa_rr = zone.find_rdataset(zone.origin, RRTYPE_SOA).items[0]
        
        update_soa_serial_flag = False
        curr_serial_no = self.get_serial_no(zone)
        # In case of a DR failover, our DB can have a more recent serial number
        # than in name server
        try:
            new_serial_no = new_soa_serial_no(curr_serial_no, zone_name, 
                    db_soa_serial=db_soa_serial,
                    candidate=candidate_soa_serial,
                    wrap_serial_next_time=wrap_serial_next_time,
                    date_stamp=date_stamp)
        except SOASerialError as exc:
            msg = str(exc)
            if (not sys.stdin.isatty()):
                log_critical(msg)
            return (RCODE_FATAL, msg, None, None)
        if wrap_serial_next_time or force_soa_serial_update:
            # Apply serial number to SOA record.
            zi.update_soa_serial(new_serial_no)
        else:
            # An increment should only be performed after difference
            update_soa_serial_flag = True

        # Compare server_zone with zi.rrs
        # Find additions and deletions
        del_rrs = [rr for rr in zone.iterate_rdatas()
                    if rr not in zi.iterate_dnspython_rrs()]
        add_rrs = [rr for rr in zi.iterate_dnspython_rrs()
                    if rr not in zone.iterate_rdatas()]
        # Check if DNSSEC settings need to be changed 
        do_clear_nsec3 = clear_nsec3 and nsec3param_flag
        do_clear_dnskey = clear_dnskey and dnskey_flag
        do_nsec3_seed = nsec3_seed and not nsec3param_flag

        if (not del_rrs and not add_rrs and not do_clear_nsec3 
                and not do_clear_dnskey and not do_nsec3_seed):
            msg = ("Domain '%s' not updated as no change detected" 
                        % (zone_name))
            return (RCODE_NOCHANGE, msg, curr_serial_no, update_info)
      
        # Incremental update of SOA serial number
        soa_rdtype = dns.rdatatype.from_text(RRTYPE_SOA)
        if update_soa_serial_flag:
            # Apply serial number to SOA record.
            zi.update_soa_serial(new_serial_no)
            # recalculate add_rrs - got to be done or else updates will be
            # missed
            add_rrs = [rr for rr in zi.iterate_dnspython_rrs()
                        if rr not in zone.iterate_rdatas()]
       
        # Groom updates for DynDNS update perculiarities

        # SOA can never be deleted RFC 2136 Section 3.4.2.3 and 3.4.2.4
        # so skip this.
        del_rrs = [rr for rr in del_rrs 
                if (rr[2].rdtype != soa_rdtype)]

        # Can never delete the last NS on the root of a zone,
        # so pre add all '@' NS records (RFC 2136 Sec
        # 3.4.2.4)
        tl_label = dns.name.from_text('@', origin=dns.name.empty)
        ns_rdtype = dns.rdatatype.from_text(RRTYPE_NS)
        pre_add_rrs = [rr for rr in add_rrs 
                        if (rr[0] == tl_label and rr[2].rdtype == ns_rdtype)]
        tl_ns_rdata = [rr[2] for rr in pre_add_rrs]
        add_rrs = [rr for rr in add_rrs if rr not in pre_add_rrs]
        # Remove '@' NS delete from del_rrs if record in pre_add_rrs 
        # ie, we are just doing a TTL update!
        del_rrs = [rr for rr in del_rrs 
                    if (not(rr[0] == tl_label and rr[2] in tl_ns_rdata))]

        # CNAMEs can only be added to vacant nodes, or totally replace 
        # RRSET on a node RFC 2136 Section 3.4.2.2
        # Choose to enforce this at zi API level.

        # DNSSEC processing - prepare NSEC3PARM rdata 
        if do_nsec3_seed:
            rn = random.getrandbits(int(settings['nsec3_salt_bit_length']))
            hash_alg = settings['nsec3_hash_algorithm']
            flags = settings['nsec3_flags']
            iterations = settings['nsec3_iterations']
            nsec3param_rdata = ("%s %s %s %016x" 
                                % (hash_alg, flags, iterations, rn))
            # Test rn as random can produce garbage sometimes...
            rdata_list = nsec3param_rdata.split()
            try:
                # This is the piece of code where dnspython blows up...
                stuff = bytes.fromhex(rdata_list[-1])
            except Exception:
                msg = ("Failed to seed NSEC3 salt - SM reset required")
                return (RCODE_RESET, msg, None, update_info)

        # Prepare dnspython tsigkeyring
        keyring = dns.tsigkeyring.from_text({
            self.key_name : self.tsig_key['secret'] })
        if (self.tsig_key['algorithm'] == 'hmac-md5'):
            key_algorithm = dns.tsig.HMAC_MD5
        else:
            key_algorithm = dns.name.from_text(self.tsig_key['algorithm'])
        
        # Create update 
        # We have to use absolute FQDNs on LHS  and RHS to make sure updates
        # to NS etc happen
        # While doing this also handle wee things for DNSSEC processing
        origin = dns.name.from_text(zone_name)
        update = dns.update.Update(origin, keyring=keyring,
                    keyname = self.key_name, keyalgorithm=key_algorithm)
        update.present(origin, current_soa_rr)
        for rr in pre_add_rrs:
            update.add(rr[0], rr[1], rr[2])
        for rr in del_rrs:
            update.delete(rr[0], rr[2])
        # Add DNSSEC clearance stuff to end of delete section of update
        if do_clear_nsec3:
            update.delete(origin, RRTYPE_NSEC3PARAM)
        if do_clear_dnskey:
            update.delete(origin, RRTYPE_DNSKEY)
        for rr in add_rrs:
            update.add(rr[0], rr[1], rr[2])
        # NSEC3PARAM seeding
        if do_nsec3_seed:
            update.add(origin, '0', RRTYPE_NSEC3PARAM, nsec3param_rdata)

        # Do dee TING!
        response = dns.query.tcp(update, self.server, port=self.port)

        # Process reply
        rcode = response.rcode()
        rcode_text = dns.rcode.to_text(response.rcode())
        success_rcodes = (dns.rcode.NOERROR)
        if (rcode in self.success_rcodes):
            msg = ("Update '%s' to domain '%s' succeeded" 
                            % (new_serial_no, zone_name))
            return (RCODE_OK, msg, new_serial_no, update_info)
        elif (rcode in self.retry_rcodes):
            msg = ("Update '%s' to domain '%s' failed: %s - will retry"
                        % (new_serial_no, zone_name, rcode_text))
            return (RCODE_ERROR, msg, None, update_info)
        elif (rcode in self.reset_rcodes):
            msg = ("Update '%s' to domain '%s' failed: %s - SM reset required"
                        % (new_serial_no, zone_name, rcode_text))
            return (RCODE_RESET, msg, None, update_info)
        elif (rcode in self.fatal_rcodes):
            msg = ("Update '%s' to domain '%s' permanently failed: %s"
                        % (new_serial_no, zone_name, rcode_text))
            return (RCODE_FATAL, msg, None, update_info)
        else:
            msg = ("Update '%s' to domain '%s' permanently failed: '%s'"
                    " - unknown response"
                        % (new_serial_no, zone_name, response.rcode()))
            return (RCODE_FATAL, msg, None, update_info)
Beispiel #23
0
        # Define the response of a successful execution of the function
        http_status = 200
        prog_status = 0
        explanation = "Successfully created specified SRV record (Service: {} Port: {} A Record: {})".format(
            service_name, service_port, A_record)

        domain = "simplicify.com"
        zone_file = "/etc/bind/zones/db.%s" % domain
        new_zone_file = "new.db.%s" % domain
        try:
            zone = dns.zone.from_file(zone_file, domain)
        except DNSException, e:
            print e.__class__, e
        n = dns.name.from_text(A_record)
        rdataset = zone.find_rdataset(service_name, rdtype='SRV', create=True)
        rdata = dns.rdtypes.IN.SRV.SRV(IN, SRV, 0, 0, service_port, target=n)
        rdataset.add(rdata, ttl=86400)
        print str(rdataset)
        print str(rdata)
        try:
            zone.to_file(new_zone_file)
        except:
            explanation = "An unknown error occurred adding the specified SRV record (Service: {} Port: {} A Record: {})".format(
                service_name, service_port, A_record)
            status = 500
            return [1, status, explanation, ""]

        payload = ""
        returns = [prog_status, http_status, explanation, payload]
Beispiel #24
0
class commands:
    def __init__(self, simplicify):
        self.config = simplicify.SimplicifyConfig

    def ls_SRV(self, service_name):
        """
        Note: This function retrieves all configured S
        Args:
            service_name:  The symbolic name of the desired service, as defined in Assigned
        Numbers [STD 2] or locally.  An underscore (_) is prepended to
        the service identifier to avoid collisions with DNS labels that
        occur in nature.

        Returns:
            returns: Array containing the program status code, http status code, humanly readable explanation, and payload

        """

        # Define the response of a successful execution of the function
        http_status = 200
        prog_status = 0
        explanation = "Successfully listed all service records with the specified service name ({})".format(
            service_name)

        try:
            response = dns.resolver.query(service_name, 'SRV')
        except:
            explanation = "An unknown error occurred listing records for the specified service ({})".format(
                service_name)
            status = 500
            return [1, status, explanation, ""]

        results_list = []
        for rdata in response:
            results_list.append(str(rdata.target).rstrip('.'))

        payload = results_list
        returns = [prog_status, http_status, explanation, payload]

        return returns

    def ls_A(self, dns_name):
        """
        Note: This function retrieves all configured S
        Args:
            service_name:  The symbolic name of the desired service, as defined in Assigned
        Numbers [STD 2] or locally.  An underscore (_) is prepended to
        the service identifier to avoid collisions with DNS labels that
        occur in nature.

        Returns:
            returns: Array containing the program status code, http status code, humanly readable explanation, and payload

        """

        # Define the response of a successful execution of the function
        http_status = 200
        prog_status = 0
        explanation = "Successfully listed all service records with the specified DNS name ({})".format(
            dns_name)

        try:
            response = dns.resolver.query(dns_name, 'A')
        except:
            explanation = "An unknown error occurred listing records for the specified DNS name ({})".format(
                dns_name)
            status = 500
            return [1, status, explanation, ""]

        results_list = []
        for rdata in response:
            results_list.append(str(rdata))

        payload = results_list
        returns = [prog_status, http_status, explanation, payload]

        return returns

    def create_A(self, record_name, ip_address):
        """
        Note: This function creates an A record on a bind9 DNS server
        Args:
            record_name:  FQDN for record

        Returns:
            returns: Array containing the program status code, http status code, humanly readable explanation, and payload

        """

        # Define the response of a successful execution of the function
        http_status = 200
        prog_status = 0
        explanation = "Successfully created specified A record ({})".format(
            record_name)

        domain = "simplicify.com"
        print "Getting zone object for domain", domain
        zone_file = "/etc/bind/zones/db.%s" % domain

        try:
            zone = dns.zone.from_file(zone_file, domain)
            print "Zone origin:", zone.origin
        except DNSException, e:
            print e.__class__, e

        rdataset = zone.find_rdataset(record_name, rdtype=A, create=True)
        rdata = dns.rdtypes.IN.A.A(IN, A, address=ip_address)
        rdataset.add(rdata, ttl=86400)
        new_zone_file = "new.db.%s" % domain

        try:
            zone.to_file(new_zone_file)
        except:
            explanation = "An unknown error occurred adding the specified A record ({})".format(
                dns_name)
            status = 500
            return [1, status, explanation, ""]

        payload = ""
        returns = {
            "prog_status": prog_status,
            "http_status": http_status,
            "explanation": explanation,
            "payload": payload
        }
        return returns