Beispiel #1
0
 def reset_all_zones(self):
     """
     Reset all zones
     """
     self._begin_op()
     db_session = self.db_session
     id_query = db_session.query(ZoneSM.id_, ZoneSM.name)
     id_query = ZoneSM.query_is_not_disabled_deleted(id_query)
     id_result = id_query.all()
     for zone_id, zone_name in id_result:
         try:
             zone_sm = db_session.query(ZoneSM)\
                     .filter(ZoneSM.id_ == zone_id).one()
         except NoResultFound:
             raise ZoneNotFoundByZoneId(zone_id)
         exec_zonesm(zone_sm, ZoneSMDoReset)
     self._finish_op()
Beispiel #2
0
 def refresh_sg(self, sg_name):
     """
     Refresh all zones on an SG
     """
     self._begin_op()
     db_session = self.db_session
     sg = self._find_sg_byname(sg_name)
     id_query = db_session.query(ZoneSM.id_, ZoneSM.name)\
             .filter(ZoneSM.sg_id == sg.id_) 
     id_query = ZoneSM.query_is_configured(id_query)
     id_result = id_query.all()
     for zone_id, zone_name in id_result:
         try:
             zone_sm = db_session.query(ZoneSM)\
                     .filter(ZoneSM.id_ == zone_id).one()
         except NoResultFound:
             raise ZoneNotFoundByZoneId(zone_id)
         exec_zonesm(zone_sm, ZoneSMDoRefresh)
     self._finish_op()
Beispiel #3
0
    def _queue_auto_ptr_data(self, auto_ptr_data):
        """
        Queue auto PTR data as incremental updates against respective reverse
        zones.
        """
        if not auto_ptr_data:
            return
        if not len(auto_ptr_data):
            return
        if not settings['auto_reverse']:
            return
        db_session = self.db_session
        # Create new update_group
        ug_dict = {}
        auto_ptr_privilege_flag = False
        for ptr_data in auto_ptr_data:
            # Ignore addresses we don't have reverse zone for
            query = db_session.query(ZoneSM)\
                    .join(ReverseNetwork)\
                    .filter(":address  <<= reverse_networks.network")\
                    .params(address = ptr_data['address'])
            query = ZoneSM.query_is_not_deleted(query)
            query = ZoneSM.query_inc_updates(query)
            query = query.order_by(ReverseNetwork.network.desc())\
                    .limit(1)
            try:
                zone_sm = query.one()
            except NoResultFound:
                continue

            # Ignore invalid host names
            if not is_inet_hostname(ptr_data['hostname'], absolute=True,
                                    wildcard=False):
                log_error("Hostname '%s' is not a valid hostname." 
                        % ptr_data['hostname'])
                continue

            # Determine proposed update operation
            update_op = RROP_PTR_UPDATE_FORCE if ptr_data['force_reverse'] \
                            else RROP_PTR_UPDATE

            # Execute privilege checks ahead of time to save unnecessary churn
            # Better than needlessly going through whole rigamorole of 
            # incremental update processing later on for no effect
            #1 See if old PTR exists to retrieve any RR reference
            # Both following also used lower down when generating RR_PTR
            label = label_from_address(ptr_data['address'])
            rr_ref = find_reference(db_session, ptr_data['reference'],
                                        raise_exc=False)
            # query for old record - this generates one select
            # Optimization  - if check has previously suceeded, don't check
            # again as this is all checked further in
            if not auto_ptr_privilege_flag:
                qlabel= label[:label.rfind(zone_sm.name)-1]
                query = db_session.query(ResourceRecord)\
                    .filter(ResourceRecord.label == qlabel)\
                    .filter(ResourceRecord.zi_id == zone_sm.zi_candidate_id)\
                    .filter(ResourceRecord.disable == False)\
                    .filter(ResourceRecord.type_ == RRTYPE_PTR)
                old_rrs = query.all()
                old_rr = old_rrs[0] if len(old_rrs) else None
                
            # Check that we can proceed, only if check has not succeded yet
                if not check_auto_ptr_privilege(rr_ref, self.sectag, zone_sm,
                    old_rr):
                    if old_rr:
                        log_debug("Zone '%s' - can't replace '%s' PTR"
                            " as neither"
                            " sectags '%s' vs '%s'"
                            " references '%s' vs '%s'/'%s' (old PTR/rev zone)"
                            "match ,"
                            " or values not given."
                        % (zone_sm.name, old_rr.label,
                            self.sectag.sectag, settings['admin_sectag'],    
                            rr_ref, old_rr.reference, zone_sm.reference))
                    else:
                        log_debug("Zone '%s' - can't add '%s' PTR as neither"
                                " sectags '%s' vs '%s'"
                                " references '%s' vs '%s' (rev zone) match,"
                                " or values not given."
                            % (zone_sm.name, qlabel,
                                self.sectag.sectag, settings['admin_sectag'],    
                                rr_ref, zone_sm.reference))
                    continue
                auto_ptr_privilege_flag = True

            # Create a new update group if zone has not been seen before.
            try:
                update_group, zone_ttl = ug_dict.get(zone_sm)
            except (ValueError, TypeError):
                # Obtain reverse zone_ttl so PTR rrs can be created
                # Use candidate ZI as it always is available.
                # zi is published zi
                zi = self._get_zi(zone_sm.zi_candidate_id)
                if not zi:
                    log_error("Zone '%s': does not have candidate zi." 
                                % zone_sm.name)
                    continue
                zone_ttl = zi.zone_ttl
                update_group = new_update_group(db_session, None, 
                                        zone_sm, None, ptr_only=True, 
                                        sectag=self.sectag.sectag)
                ug_dict[zone_sm] = (update_group, zone_ttl)
            
            # Allocate RR_PTR update record
            rr = RR_PTR(label=label, zone_ttl=zone_ttl, 
                    rdata=ptr_data['hostname'], disable=ptr_data['disable'],
                    domain=zone_sm.name, update_op=update_op)
            rr.ref_id = rr_ref.id_ if rr_ref else None
            rr.reference = rr_ref

            # Chain on  RR_PTR update record
            update_group.update_ops.append(rr)

        # Flush everything to disk
        db_session.flush()
        # Issue zone refreshes to implement PTR changes
        for zone_sm in ug_dict:
            if zone_sm.is_disabled():
                continue
            exec_zonesm(zone_sm, ZoneSMDoRefresh)
        # Make sure everything is committed
        db_session.commit()
Beispiel #4
0
    def restore_named_db(self):
        """
        Dump dms DB to Named zone files and include file

        For quick DR secnario
        """
        self._begin_op()
        
        # Exception processing make the both of the following a bit of a 
        # rats nest
        # Check that named is not running
        cmdline = [settings['rndc_path'], 'status']
        try:
            check_output(cmdline, stderr=STDOUT)
        except CalledProcessError as exc:
            if exc.returncode != 1:
                raise exc
            pass
        else:
            raise NamedStillRunning(0)

        # Check that dmsdmd is not running
        try:
            pid_file = open(settings['pid_file'],'r')
            dmsdmd_pid = int(pid_file.readline().strip())
            pid_file.close()
            # The following throws exceptions if process does not exist etc!
            # Sending signal 0 does not touch process, but  call succeeds
            # if it exists
            os.kill(dmsdmd_pid, 0)
        except ValueError as exc:
            # Error from int() type conversion above
            raise PidFileValueError(pid_file, exc)
        except (IOError,OSError) as exc:
            if (exc.errno in (errno.ESRCH,)):
                # This is from kill()
                raise DmsdmdStillRunning(dmsdmd_pid)
            # File IO causes this
            elif (exc.errno in (errno.ENOENT,)):
                # This file may be removed by dameon nicely shutting down.
                pass
        else:
            # No exceptions, dmsdmd is running!!!
            raise DmsdmdStillRunning(dmsdmd_pid)

        # Dump out each zone file
        db_session = self.db_session
        id_query = db_session.query(ZoneSM.id_, ZoneSM.name)
        id_query = ZoneSM.query_is_not_disabled_deleted(id_query)
        id_result = id_query.all()
        for zone_id, zone_name in id_result:
            try:
                zone_sm = db_session.query(ZoneSM)\
                        .filter(ZoneSM.id_ == zone_id).one()
            except NoResultFound:
                raise ZoneNotFoundByZoneId(zone_id)
            try:
                zone_sm.write_zone_file(db_session, ZoneFileWriteInternalError)
                zone_sm.state = ZSTATE_PUBLISHED
                db_session.commit()
            except ZoneFileWriteInternalError as exc:
                db_session.rollback()
                raise ZoneFileWriteError(str(exc))
        
        # Write out config file include
        master_sm = get_master_sm(db_session)
        try:
            master_sm.write_named_conf_includes(db_session, 
                    NamedConfWriteInternalError)
        except NamedConfWriteInternalError as exc:
            raise NamedConfWriteError(str(exc))
        self._finish_op()
Beispiel #5
0
    def _queue_auto_ptr_data(self, auto_ptr_data):
        """
        Queue auto PTR data as incremental updates against respective reverse
        zones.
        """
        if not auto_ptr_data:
            return
        if not len(auto_ptr_data):
            return
        if not settings['auto_reverse']:
            return
        db_session = self.db_session
        # Create new update_group
        ug_dict = {}
        auto_ptr_privilege_flag = False
        for ptr_data in auto_ptr_data:
            # Ignore addresses we don't have reverse zone for
            query = db_session.query(ZoneSM)\
                    .join(ReverseNetwork)\
                    .filter(text(":address  <<= reverse_networks.network"))\
                    .params(address = ptr_data['address'])
            query = ZoneSM.query_is_not_deleted(query)
            query = ZoneSM.query_inc_updates(query)
            query = query.order_by(ReverseNetwork.network.desc())\
                    .limit(1)
            try:
                zone_sm = query.one()
            except NoResultFound:
                continue

            # Ignore invalid host names
            if not is_inet_hostname(
                    ptr_data['hostname'], absolute=True, wildcard=False):
                log_error("Hostname '%s' is not a valid hostname." %
                          ptr_data['hostname'])
                continue

            # Determine proposed update operation
            update_op = RROP_PTR_UPDATE_FORCE if ptr_data['force_reverse'] \
                            else RROP_PTR_UPDATE

            # Execute privilege checks ahead of time to save unnecessary churn
            # Better than needlessly going through whole rigamorole of
            # incremental update processing later on for no effect
            #1 See if old PTR exists to retrieve any RR reference
            # Both following also used lower down when generating RR_PTR
            label = label_from_address(ptr_data['address'])
            rr_ref = find_reference(db_session,
                                    ptr_data['reference'],
                                    raise_exc=False)
            # query for old record - this generates one select
            # Optimization  - if check has previously suceeded, don't check
            # again as this is all checked further in
            if not auto_ptr_privilege_flag:
                qlabel = label[:label.rfind(zone_sm.name) - 1]
                query = db_session.query(ResourceRecord)\
                    .filter(ResourceRecord.label == qlabel)\
                    .filter(ResourceRecord.zi_id == zone_sm.zi_candidate_id)\
                    .filter(ResourceRecord.disable == False)\
                    .filter(ResourceRecord.type_ == RRTYPE_PTR)
                old_rrs = query.all()
                old_rr = old_rrs[0] if len(old_rrs) else None

                # Check that we can proceed, only if check has not succeded yet
                if not check_auto_ptr_privilege(rr_ref, self.sectag, zone_sm,
                                                old_rr):
                    if old_rr:
                        log_debug(
                            "Zone '%s' - can't replace '%s' PTR"
                            " as neither"
                            " sectags '%s' vs '%s'"
                            " references '%s' vs '%s'/'%s' (old PTR/rev zone)"
                            "match ,"
                            " or values not given." %
                            (zone_sm.name, old_rr.label, self.sectag.sectag,
                             settings['admin_sectag'], rr_ref,
                             old_rr.reference, zone_sm.reference))
                    else:
                        log_debug("Zone '%s' - can't add '%s' PTR as neither"
                                  " sectags '%s' vs '%s'"
                                  " references '%s' vs '%s' (rev zone) match,"
                                  " or values not given." %
                                  (zone_sm.name, qlabel, self.sectag.sectag,
                                   settings['admin_sectag'], rr_ref,
                                   zone_sm.reference))
                    continue
                auto_ptr_privilege_flag = True

            # Create a new update group if zone has not been seen before.
            try:
                update_group, zone_ttl = ug_dict.get(zone_sm)
            except (ValueError, TypeError):
                # Obtain reverse zone_ttl so PTR rrs can be created
                # Use candidate ZI as it always is available.
                # zi is published zi
                zi = self._get_zi(zone_sm.zi_candidate_id)
                if not zi:
                    log_error("Zone '%s': does not have candidate zi." %
                              zone_sm.name)
                    continue
                zone_ttl = zi.zone_ttl
                update_group = new_update_group(db_session,
                                                None,
                                                zone_sm,
                                                None,
                                                ptr_only=True,
                                                sectag=self.sectag.sectag)
                ug_dict[zone_sm] = (update_group, zone_ttl)

            # Allocate RR_PTR update record
            rr = RR_PTR(label=label,
                        zone_ttl=zone_ttl,
                        rdata=ptr_data['hostname'],
                        disable=ptr_data['disable'],
                        domain=zone_sm.name,
                        update_op=update_op)
            rr.ref_id = rr_ref.id_ if rr_ref else None
            rr.reference = rr_ref

            # Chain on  RR_PTR update record
            update_group.update_ops.append(rr)

        # Flush everything to disk
        db_session.flush()
        # Issue zone refreshes to implement PTR changes
        for zone_sm in ug_dict:
            if zone_sm.is_disabled():
                continue
            exec_zonesm(zone_sm, ZoneSMDoRefresh)
        # Make sure everything is committed
        db_session.commit()