Ejemplo n.º 1
0
def test_str_stp() -> None:  # noqa: D103
    stp_str = "urn:ogf:network:netherlight.net:2013:production7:netherlight-of-1?vlan=200-500,1779-1799"
    stp = parse_stp(stp_str)
    assert str(stp) == stp_str

    # without labels
    stp_str = "urn:ogf:network:netherlight.net:2013:production7:netherlight-of-1"
    stp = parse_stp(stp_str)
    assert str(stp) == stp_str
Ejemplo n.º 2
0
def test_stp_vlan_ranges() -> None:  # noqa: D103
    stp = parse_stp(
        "urn:ogf:network:netherlight.net:2013:production7:netherlight-of-1?vlan=200-500,1779-1799"
    )
    assert stp.vlan_ranges == VlanRanges("200-500,1779-1799")

    stp = parse_stp(
        "urn:ogf:network:netherlight.net:2013:production7:netherlight-of-1?vlan=1799"
    )
    assert stp.vlan_ranges == VlanRanges(1799)

    stp = parse_stp(
        "urn:ogf:network:netherlight.net:2013:production7:netherlight-of-1")
    assert stp.vlan_ranges == VlanRanges()
Ejemplo n.º 3
0
def test_parse_stp_with_year_no_labels() -> None:  # noqa: D103
    stp = parse_stp(
        "urn:ogf:network:netherlight.net:2013:production7:netherlight-of-1")
    assert stp.domain == "netherlight.net:2013"
    assert stp.network_type == "production7"
    assert stp.port == "netherlight-of-1"
    assert stp.labels is None  # <-- no labels
Ejemplo n.º 4
0
def test_parse_stp_with_year_qualified() -> None:  # noqa: D103
    stp = parse_stp(
        "urn:ogf:network:netherlight.net:2013:production7:netherlight-of-1?vlan=1779"
    )
    assert stp.domain == "netherlight.net:2013"
    assert stp.network_type == "production7"
    assert stp.port == "netherlight-of-1"
    assert stp.labels == "vlan=1779"  # <-- qualified
Ejemplo n.º 5
0
def test_parse_stp_without_year_unqualified() -> None:  # noqa: D103
    stp = parse_stp(
        "urn:ogf:network:netherlight.net:production7:netherlight-of-1?vlan=200-500,1779-1799"
    )
    assert stp.domain == "netherlight.net"  # <-- without year
    assert stp.network_type == "production7"
    assert stp.port == "netherlight-of-1"
    assert stp.labels == "vlan=200-500,1779-1799"
Ejemplo n.º 6
0
def test_parse_stp_missing_domain() -> None:  # noqa: D103
    with pytest.raises(ValueError):
        parse_stp(
            "urn:ogf:network:2013:production7:netherlight-of-1?vlan=200-500,1779-1799"
        )
Ejemplo n.º 7
0
def test_parse_stp_missing_port() -> None:  # noqa: D103
    with pytest.raises(ValueError):
        parse_stp("urn:ogf:network:netherlight.net:2013:production7")
Ejemplo n.º 8
0
def test_parse_stp_missing_network_type() -> None:  # noqa: D103
    with pytest.raises(ValueError):
        parse_stp(
            "urn:ogf:network:netherlight.net:2013:netherlight-of-1?vlan=200-500,1779-1799"
        )
Ejemplo n.º 9
0
    def Reserve(self, pb_reserve_request: ReserveRequest, context: ServicerContext) -> ReserveResponse:
        """Request new reservation, or modify existing reservation.

        The reserve message is sent from an RA to a PA when a new reservation is being requested, or
        a modification to an existing reservation is required. The :class:`ReserveResponse` indicates that the PA
        has accepted the reservation request for processing and has assigned it the returned
        connectionId. The original ``connection_id`` will be returned for the :class:`ReserveResponse`` of a
        modification. A :class:`ReserveConfirmed` or :class:`ReserveFailed` message will be sent asynchronously to the
        RA when reserve operation has completed processing.

        Args:
            pb_reserve_request: All the details about the requested reservation.
            context: gRPC server context object.

        Returns:
            A :class:`ReserveResponse` message containing the PA assigned ``connection_id`` for this reservation
            request. This value will be unique within the context of the PA.

        """
        log = logger.bind(method="Reserve")
        log.info("Received message.", request_message=pb_reserve_request)

        if not pb_reserve_request.connection_id:  # new reservation
            pb_header: Header = pb_reserve_request.header
            pb_criteria: ReservationRequestCriteria = pb_reserve_request.criteria
            pb_schedule: Schedule = pb_criteria.schedule
            start_time = as_utc_timestamp(pb_schedule.start_time)
            end_time = as_utc_timestamp(pb_schedule.end_time)
            pb_ptps: PointToPointService = pb_criteria.ptps
            pb_path_trace: PathTrace = pb_header.path_trace

            reservation = model.Reservation(
                correlation_id=UUID(pb_header.correlation_id),
                protocol_version=pb_header.protocol_version,
                requester_nsa=pb_header.requester_nsa,
                provider_nsa=pb_header.provider_nsa,
                reply_to=pb_header.reply_to if pb_header.reply_to else None,
                session_security_attributes=pb_header.session_security_attributes
                if pb_header.session_security_attributes
                else None,
                global_reservation_id=pb_reserve_request.global_reservation_id,
                description=pb_reserve_request.description if pb_reserve_request.description else None,
                version=pb_criteria.version,
            )
            if is_specified(end_time):
                if end_time <= start_time:
                    raise Exception(f"End time cannot come before the start time. {start_time=!s}, {end_time=!s}")
                elif end_time <= current_timestamp():
                    raise Exception(f"End time lies in the past. {end_time=!s}")
            if is_specified(start_time):
                reservation.start_time = start_time
            if is_specified(end_time):
                reservation.end_time = end_time
            reservation.bandwidth = pb_ptps.capacity
            reservation.directionality = Directionality.Name(pb_ptps.directionality)
            reservation.symmetric = pb_ptps.symmetric_path

            src_stp = parse_stp(pb_ptps.source_stp)
            reservation.src_domain = src_stp.domain
            reservation.src_network_type = src_stp.network_type
            reservation.src_port = src_stp.port
            reservation.src_vlans = str(src_stp.vlan_ranges)

            dst_stp = parse_stp(pb_ptps.dest_stp)
            reservation.dst_domain = dst_stp.domain
            reservation.dst_network_type = dst_stp.network_type
            reservation.dst_port = dst_stp.port
            reservation.dst_vlans = str(dst_stp.vlan_ranges)

            for k, v in pb_ptps.parameters.items():
                reservation.parameters.append(model.Parameter(key=k, value=v))

            if pb_path_trace.id:
                path_trace = model.PathTrace(
                    path_trace_id=pb_path_trace.id, ag_connection_id=pb_path_trace.connection_id
                )
                for pb_path in pb_path_trace.paths:
                    path = model.Path()
                    for pb_segment in pb_path.segments:
                        segment = model.Segment(segment_id=pb_segment.id, upa_connection_id=pb_segment.connection_id)
                        for pb_stp in pb_segment.stps:
                            segment.stps.append(model.Stp(stp_id=pb_stp))
                        path.segments.append(segment)
                    path_trace.paths.append(path)
                reservation.path_trace = path_trace

            rsm = ReservationStateMachine(reservation, state_field="reservation_state")
            rsm.reserve_request()

            from supa.db.session import db_session

            with db_session() as session:
                session.add(reservation)
                session.flush()  # Let DB (actually SQLAlchemy) generate the connection_id for us.
                connection_id = reservation.connection_id  # Can't reference it outside of the session, hence new var.

        # TODO modify reservation (else clause)

        from supa import scheduler

        scheduler.add_job(ReserveJob(connection_id))
        reserve_response = ReserveResponse(header=pb_reserve_request.header, connection_id=str(connection_id))

        log.info("Sending response.", response_message=reserve_response)
        return reserve_response