示例#1
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()
示例#2
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()
示例#3
0
    def _data_to_update(self, name, update_data, update_type, change_by,
            admin_privilege=False, helpdesk_privilege=False):
        """
        Construct an update group for a zone, from supplied RRS and comments.

        Functional equivalent of _data_to_zi() above, but for incremental 
        updates
        """
        # Function start
        db_session = self.db_session
        # Check that update_type is supplied
        if not update_type:
            raise UpdateTypeRequired(name)
        # Get zone_sm to get zone ID etc
        zone_sm = self._get_zone_sm(name)
        zone_id = zone_sm.id_

        # See if incremental updates are enabled for zone before queuing any
        if not zone_sm.inc_updates:
            raise IncrementalUpdatesDisabled(name)
        # Don't queue updates for a disabled zone
        if zone_sm.is_disabled():
            raise ZoneDisabled(name)
        # Privilege check for no apex zones - admin only 
        if not zone_sm.use_apex_ns and not admin_privilege:
            raise ZoneAdminPrivilegeNeeded(name)
       
        # Use candidate ZI as it always is available.  zi is published zi
        zi = self._get_zi(zone_sm.zi_candidate_id)
        if not zi:
            raise ZiNotFound(name, zone_sm.zi_candidate_id)

        # Get value of zone_ttl so that RRs can be created
        zone_ttl = zi.zone_ttl

        # Create RRs list from published ZI
        pzi = PseudoZi(db_session, zi)

        # initialise data and zone consistency checking
        zi_cname_flag = False
        if len([r for r in pzi.rrs if r.type_ == RRTYPE_CNAME]):
            zi_cname_flag = True
        data_tools = DataTools(db_session, zone_sm, zi_cname_flag)

        # Create comments, and set up comment IDs, and stuff for handlng
        # RR Groups zi_data structures
        data_tools.rr_data_create_comments(update_data, zone_ttl, 
                        creating_real_zi=False)
        try:
            # Create new update_group
            update_group = new_update_group(db_session, update_type, 
                                zone_sm, change_by)
        except IntegrityError as exc:
            raise UpdateTypeAlreadyQueued(name, update_type)

        # Add RRs to DB and operate on Pseudo ZI
        data_tools.add_rrs(lambda :pzi.rrs, pzi.trial_op_rr,
            admin_privilege, helpdesk_privilege, update_group=update_group)

        data_tools.check_zi_consistency(pzi.rrs)

        # Get all data out to DB, and ids etc established.
        db_session.flush()
        # Refresh zone to implement updates
        exec_zonesm(zone_sm, ZoneSMDoRefresh)

        # Return auto update info
        return data_tools.get_auto_ptr_data()
示例#4
0
    def _data_to_update(self,
                        name,
                        update_data,
                        update_type,
                        change_by,
                        admin_privilege=False,
                        helpdesk_privilege=False):
        """
        Construct an update group for a zone, from supplied RRS and comments.

        Functional equivalent of _data_to_zi() above, but for incremental 
        updates
        """
        # Function start
        db_session = self.db_session
        # Check that update_type is supplied
        if not update_type:
            raise UpdateTypeRequired(name)
        # Get zone_sm to get zone ID etc
        zone_sm = self._get_zone_sm(name)
        zone_id = zone_sm.id_

        # See if incremental updates are enabled for zone before queuing any
        if not zone_sm.inc_updates:
            raise IncrementalUpdatesDisabled(name)
        # Don't queue updates for a disabled zone
        if zone_sm.is_disabled():
            raise ZoneDisabled(name)
        # Privilege check for no apex zones - admin only
        if not zone_sm.use_apex_ns and not admin_privilege:
            raise ZoneAdminPrivilegeNeeded(name)

        # Use candidate ZI as it always is available.  zi is published zi
        zi = self._get_zi(zone_sm.zi_candidate_id)
        if not zi:
            raise ZiNotFound(name, zone_sm.zi_candidate_id)

        # Get value of zone_ttl so that RRs can be created
        zone_ttl = zi.zone_ttl

        # Create RRs list from published ZI
        pzi = PseudoZi(db_session, zi)

        # initialise data and zone consistency checking
        zi_cname_flag = False
        if len([r for r in pzi.rrs if r.type_ == RRTYPE_CNAME]):
            zi_cname_flag = True
        data_tools = DataTools(db_session, zone_sm, zi_cname_flag)

        # Create comments, and set up comment IDs, and stuff for handlng
        # RR Groups zi_data structures
        data_tools.rr_data_create_comments(update_data,
                                           zone_ttl,
                                           creating_real_zi=False)
        try:
            # Create new update_group
            update_group = new_update_group(db_session, update_type, zone_sm,
                                            change_by)
        except IntegrityError as exc:
            raise UpdateTypeAlreadyQueued(name, update_type)

        # Add RRs to DB and operate on Pseudo ZI
        data_tools.add_rrs(lambda: pzi.rrs,
                           pzi.trial_op_rr,
                           admin_privilege,
                           helpdesk_privilege,
                           update_group=update_group)

        data_tools.check_zi_consistency(pzi.rrs)

        # Get all data out to DB, and ids etc established.
        db_session.flush()
        # Refresh zone to implement updates
        exec_zonesm(zone_sm, ZoneSMDoRefresh)

        # Return auto update info
        return data_tools.get_auto_ptr_data()