Пример #1
0
 def add_rrs(self,
             rrs_func,
             add_rr_func,
             admin_privilege,
             helpdesk_privilege,
             update_group=None):
     """
     Add RR to data base
     
     Note use of rrs_func so that list of rrs is always refreshed in
     function.  Can be supplied by using a no argument lambda function.
     This is so that in the case of a full ZI, rrs can be added to it,
     which is different to the case of incremental updates, where the 
     list of RRs is constructed, and the rrs just added directly to the
     resource records table.
     """
     db_session = self.db_session
     for rr_group in self.rr_group_data:
         for rr_data in rr_group['rrs']:
             # Remove unneeded keys from rr_data
             rr_data.pop('comment', None)
             rr_data.pop('zone_id', None)
             # Check privilege
             self.check_extra_data_privilege(rr_data, admin_privilege,
                                             helpdesk_privilege)
             rr = data_to_rr(self.name, rr_data)
             self.check_rr_consistency(rrs_func(), rr, rr_data,
                                       update_group)
             # Store rr_data for zi consistency checks
             self.put_zi_rr_data(str(rr), rr_data)
             # Add rr to SQLAlchemy data structures
             db_session.add(rr)
             # Sort out RR reference part of the data structure
             rr_ref_str = rr_data.get('reference')
             if rr_ref_str:
                 self.check_reference_string(rr_ref_str)
                 rr_ref = find_reference(db_session, rr_ref_str)
                 rr.ref_id = rr_ref.id_ if rr_ref else None
                 rr.reference = rr_ref
             # Sort out update_group if given
             if update_group:
                 update_group.update_ops.append(rr)
             add_rr_func(rr)
             self.handle_auto_ptr_data(rr, rr_data)
Пример #2
0
 def add_rrs(self, rrs_func, add_rr_func, 
             admin_privilege, helpdesk_privilege,
             update_group=None):
     """
     Add RR to data base
     
     Note use of rrs_func so that list of rrs is always refreshed in
     function.  Can be supplied by using a no argument lambda function.
     This is so that in the case of a full ZI, rrs can be added to it,
     which is different to the case of incremental updates, where the 
     list of RRs is constructed, and the rrs just added directly to the
     resource records table.
     """
     db_session = self.db_session
     for rr_group in self.rr_group_data:
         for rr_data in rr_group['rrs']:
             # Remove unneeded keys from rr_data
             rr_data.pop('comment', None)
             rr_data.pop('zone_id', None)
             # Check privilege
             self.check_extra_data_privilege(rr_data, admin_privilege,
                     helpdesk_privilege)
             rr = data_to_rr(self.name, rr_data)
             self.check_rr_consistency(rrs_func(), rr, rr_data, update_group)
             # Store rr_data for zi consistency checks
             self.put_zi_rr_data(str(rr), rr_data)
             # Add rr to SQLAlchemy data structures
             db_session.add(rr)
             # Sort out RR reference part of the data structure
             rr_ref_str = rr_data.get('reference')
             if rr_ref_str: 
                 self.check_reference_string(rr_ref_str)
                 rr_ref = find_reference(db_session, rr_ref_str)
                 rr.ref_id = rr_ref.id_ if rr_ref else None
                 rr.reference = rr_ref
             # Sort out update_group if given
             if update_group:
                 update_group.update_ops.append(rr)
             add_rr_func(rr)
             self.handle_auto_ptr_data(rr, rr_data)
Пример #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()
Пример #4
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()