Esempio n. 1
0
    def upsert_rpsl_object(self,
                           rpsl_object: RPSLObject,
                           forced_serial: Optional[int] = None) -> None:
        """
        Schedule an RPSLObject for insertion/updating.

        This method will insert the object, or overwrite an existing object
        if it has the same RPSL primary key and source. No other checks are
        applied before overwriting.

        Writes may not be issued to the database immediately for performance
        reasons, but commit() will ensure all writes are flushed to the DB first.

        The forced serial is needed for mirrored sources, where this basically means:
        this call was triggered by an NRTM operation with this serial.
        """
        ip_first = str(rpsl_object.ip_first) if rpsl_object.ip_first else None
        ip_last = str(rpsl_object.ip_last) if rpsl_object.ip_last else None

        ip_size = None
        if rpsl_object.ip_first and rpsl_object.ip_last:
            ip_size = rpsl_object.ip_last.int() - rpsl_object.ip_first.int(
            ) + 1

        # In some cases, multiple updates may be submitted for the same object.
        # PostgreSQL will not allow rows proposed for insertion to have duplicate
        # constrained values - so if a second object appears with a pk/source
        # seen before, the cache must be flushed right away, or the two updates
        # will conflict.
        source = rpsl_object.parsed_data['source']
        rpsl_pk_source = rpsl_object.pk() + '-' + source
        if rpsl_pk_source in self._rpsl_pk_source_seen:
            self._flush_rpsl_object_upsert_cache()

        self._rpsl_upsert_cache.append((
            {
                'rpsl_pk': rpsl_object.pk(),
                'source': source,
                'object_class': rpsl_object.rpsl_object_class,
                'parsed_data': rpsl_object.parsed_data,
                'object_text': rpsl_object.render_rpsl_text(),
                'ip_version': rpsl_object.ip_version(),
                'ip_first': ip_first,
                'ip_last': ip_last,
                'ip_size': ip_size,
                'asn_first': rpsl_object.asn_first,
                'asn_last': rpsl_object.asn_last,
                'updated': datetime.now(timezone.utc),
            },
            forced_serial,
        ))
        self._rpsl_pk_source_seen.add(rpsl_pk_source)
        self._object_classes_modified.add(rpsl_object.rpsl_object_class)

        if len(self._rpsl_upsert_cache) > MAX_RECORDS_CACHE_BEFORE_INSERT:
            self._flush_rpsl_object_upsert_cache()
Esempio n. 2
0
    def upsert_rpsl_object(self,
                           rpsl_object: RPSLObject,
                           origin: JournalEntryOrigin,
                           rpsl_guaranteed_no_existing=False,
                           source_serial: Optional[int] = None,
                           forced_created_value: Optional[str] = None) -> None:
        """
        Schedule an RPSLObject for insertion/updating.

        This method will insert the object, or overwrite an existing object
        if it has the same RPSL primary key and source. No other checks are
        applied before overwriting.

        Writes may not be issued to the database immediately for performance
        reasons, but commit() will ensure all writes are flushed to the DB first.

        The origin indicates the origin of this change, see JournalEntryOrigin
        for the various options. The source_serial is the serial that an NRTM
        source assigned to this change, if any.

        If rpsl_guaranteed_no_existing is set to True, the caller guarantees that this
        PK is unique in the database. This essentially only applies to inserting
        RPKI psuedo-IRR objects.
        """
        self._check_write_permitted()
        if not rpsl_guaranteed_no_existing:
            self._rpsl_guaranteed_no_existing = False
        ip_first = str(rpsl_object.ip_first) if rpsl_object.ip_first else None
        ip_last = str(rpsl_object.ip_last) if rpsl_object.ip_last else None

        ip_size = None
        if rpsl_object.ip_first and rpsl_object.ip_last:
            ip_size = rpsl_object.ip_last.int() - rpsl_object.ip_first.int(
            ) + 1

        # In some cases, multiple updates may be submitted for the same object.
        # PostgreSQL will not allow rows proposed for insertion to have duplicate
        # constrained values - so if a second object appears with a pk/source
        # seen before, the buffer must be flushed right away, or the two updates
        # will conflict.
        source = rpsl_object.parsed_data['source']

        rpsl_pk_source = rpsl_object.pk() + '-' + source
        if rpsl_pk_source in self._rpsl_pk_source_seen:
            self._flush_rpsl_object_writing_buffer()

        update_time = datetime.now(timezone.utc)
        object_dict = {
            'rpsl_pk': rpsl_object.pk(),
            'source': source,
            'object_class': rpsl_object.rpsl_object_class,
            'parsed_data': rpsl_object.parsed_data,
            'object_text':
            rpsl_object.render_rpsl_text(last_modified=update_time),
            'ip_version': rpsl_object.ip_version(),
            'ip_first': ip_first,
            'ip_last': ip_last,
            'ip_size': ip_size,
            'prefix': str(rpsl_object.prefix) if rpsl_object.prefix else None,
            'prefix_length': rpsl_object.prefix_length,
            'asn_first': rpsl_object.asn_first,
            'asn_last': rpsl_object.asn_last,
            'rpki_status': rpsl_object.rpki_status,
            'scopefilter_status': rpsl_object.scopefilter_status,
            'updated': update_time,
        }
        if forced_created_value:
            object_dict['created'] = forced_created_value

        self._rpsl_upsert_buffer.append((object_dict, origin, source_serial))

        self._rpsl_pk_source_seen.add(rpsl_pk_source)
        self._object_classes_modified.add(rpsl_object.rpsl_object_class)

        if len(self._rpsl_upsert_buffer) > MAX_RECORDS_BUFFER_BEFORE_INSERT:
            self._flush_rpsl_object_writing_buffer()