Example #1
0
    def main_process(self):
        """Main process editzone
        """
        def clean_up():
            if (tmp_file):
                os.unlink(tmp_file)

        tmp_file = ''
        # Get update session object
        error_str = ''
        try:
            update_session = DynDNSUpdate(settings['dns_server'],
                                    settings['dyndns_key_file'],
                                    settings['dyndns_key_name'],
                                    )
        except (socket.error, DynDNSCantReadKeyError, IOError) as exc:
            error_str = str(exc)
        # Process above error...
        if (error_str):
            log_error("%s" % error_str)
            sys.exit(os.EX_NOHOST)

        # Do AXFR to obtain current zone data
        msg = None
        try:
            (zone, dnskey_flag, nesc3param_flag) \
                = update_session.read_zone(self.zone_name)
        except NoSuchZoneOnServerError as exc:
            msg = str(exc)
        if msg:
            log_error(msg)
            sys.exit(os.EX_NOINPUT)
            
        # Only edit zone if not wrapping SOA serial number 
        if (not settings['wrap_serial'] and not settings['update_serial']
                and not settings['nsec3_seed'] and not settings['clear_nsec3']
                and not settings['clear_dnskey']):
            # Write zone out to a temporary file
            (fd, tmp_file) = tempfile.mkstemp(prefix=settings['process_name'] + '-',
                                    suffix='.zone')
            os.close(fd)
            zone.to_file(tmp_file)

            # Edit zone data
            old_stat = os.stat(tmp_file)
            editor = self._get_editor()
            try:
                output = check_call([editor, tmp_file])
            except CalledProcessError as exc:
                log_error("editor exited with '%s'." % exc.returncode)
                sys.exit(os.EX_SOFTWARE)
                
            new_stat = os.stat(tmp_file)
            if (not settings['force_update'] 
                    and old_stat[stat.ST_MTIME] == new_stat[stat.ST_MTIME]
                    and old_stat[stat.ST_SIZE] == new_stat[stat.ST_SIZE]
                    and old_stat[stat.ST_INO] == new_stat[stat.ST_INO]):
                log_info("File '%s' unchanged after editing - exiting." % tmp_file)
                clean_up()
                sys.exit(os.EX_OK)
     
            # Read in file and form zi structure
            zone = dns.zone.from_file(tmp_file, self.zone_name)
        # At the moment these values are just for the sake of it.
        zi = ZoneInstance(soa_refresh='5m', soa_retry='5m', soa_expire='7d', soa_minimum='600')
        for rdata in zone.iterate_rdatas():
            zi.add_rr(dnspython_to_rr(rdata))

        # Update Zone in DNS
        rcode, msg, soa_serial, *stuff = update_session.update_zone(
                            self.zone_name, zi, 
                            force_soa_serial_update=not(settings['no_serial']),
                            wrap_serial_next_time=settings['wrap_serial'],
                            nsec3_seed=settings['nsec3_seed'],
                            clear_nsec3=settings['clear_nsec3'],
                            clear_dnskey=settings['clear_dnskey']
                            )

        if rcode == RCODE_NOCHANGE:
            log_info(msg)
            sys.exit(os.EX_OK)

        # Delete temporary file
        clean_up()

        if rcode == RCODE_ERROR:
            log_warning(msg)
            sys.exit(os.EX_TEMPFAIL)
        elif rcode == RCODE_RESET:
            log_error(msg)
            sys.exit(os.EX_IOERR)
        elif rcode == RCODE_FATAL:
            log_error(msg)
            sys.exit(os.EX_IOERR)

        # Everything good - Lets GO!
        if (settings['verbose']):
            log_info(msg)
        else:
            log_debug(msg)
        sys.exit(os.EX_OK)