コード例 #1
0
 def get_request_from_request(self, request: ABCAuthorityReservation, term: Term, ticket: Ticket):
     rset = ResourceSet(units=1, rtype=request.get_type())
     rset.set_resources(cset=ticket)
     result = AuthorityReservationFactory.create(resources=rset, term=term, slice_obj=request.get_slice(),
                                                 rid=request.get_reservation_id())
     result.set_sequence_in(sequence=request.get_sequence_in() + 1)
     return result
コード例 #2
0
    def finish_correct_deficit(self,
                               *,
                               reservation: ABCAuthorityReservation,
                               rset: ResourceSet = None):
        """
        Finishes correcting a deficit.
        @param rset correction
        @param reservation reservation
        @raises Exception in case of error
        """
        # We could have a partial set if there's a shortage. Go ahead and
        # install it: we'll come back later for the rest if we return a null
        # term. Alternatively, we could release them and throw an error.
        if rset is None:
            self.log_warn(
                message=
                "we either do not have resources to satisfy the request or "
                "the reservation has/will have a pending operation")
            return

        if rset.is_empty():
            reservation.set_pending_recover(pending_recover=False)
        else:
            reservation.get_resources().update(reservation=reservation,
                                               resource_set=rset)
コード例 #3
0
 def correct_deficit(self, *, reservation: ABCAuthorityReservation):
     if reservation.get_resources() is not None:
         rc = self.get_control_by_type(
             rtype=reservation.get_resources().get_type())
         if rc is not None:
             self.finish_correct_deficit(
                 rset=rc.correct_deficit(reservation=reservation),
                 reservation=reservation)
         else:
             raise AuthorityException(
                 Constants.UNSUPPORTED_RESOURCE_TYPE.format(
                     reservation.get_type()))
コード例 #4
0
    def check_incoming_extend_lease(self, request: ABCAuthorityReservation, incoming: ABCReservationMixin):
        self.assertIsNotNone(incoming)
        self.assertEqual(ReservationStates.Active, incoming.get_state())
        self.assertEqual(ReservationPendingStates.None_, incoming.get_pending_state())
        rset = incoming.get_resources()
        self.assertIsNotNone(rset)
        self.assertEqual(request.get_requested_units(), rset.get_units())
        self.assertEqual(incoming.get_term(), request.get_requested_term())

        uset = rset.get_resources()
        self.assertIsNotNone(uset)
        self.assertEqual(self.TicketUnits, uset.get_units())

        u = uset.get_set().values().__iter__().__next__()
        self.assertEqual(self.my_unit, u)
コード例 #5
0
    def check_incoming_lease(self, request: ABCAuthorityReservation, incoming: ABCReservationMixin):
        self.assertIsNotNone(incoming)

        rset = incoming.get_resources()

        self.assertIsNotNone(rset)

        self.assertEqual(request.get_requested_units(), rset.get_units())

        self.assertEqual(incoming.get_term(), request.get_requested_term())

        uset = rset.get_resources()
        self.assertIsNotNone(uset)
        self.assertEqual(self.TicketUnits, uset.get_units())

        u = uset.get_set().values().__iter__().__next__()
        self.my_unit = u
コード例 #6
0
 def get_extend_lease_request(self, authority: ABCAuthority, delegation: ABCDelegation,
                              request: ABCAuthorityReservation):
     req_start = authority.get_actor_clock().cycle_start_date(cycle=self.TicketStartCycle)
     req_new_start = authority.get_actor_clock().cycle_start_date(cycle=self.TicketEndCycle + 1)
     req_end = authority.get_actor_clock().cycle_end_date(cycle=self.TicketNewEndCycle)
     req_term = Term(start=req_start, end=req_end, new_start=req_new_start)
     rtype = ResourceType(resource_type=request.get_requested_resources().get_sliver().resource_type.name)
     ticket = self.get_ticket(self.TicketUnits, rtype, req_term, delegation, authority)
     new_request = self.get_request_from_request(request, req_term, ticket)
     return new_request
コード例 #7
0
 def modify_lease(self, *, reservation: ABCAuthorityReservation, caller: AuthToken):
     if caller is None:
         if not self.recovered:
             self.modifying_lease.add(reservation=reservation)
         else:
             self.wrapper.modify_lease_request(reservation=reservation, caller=reservation.get_client_auth_token(),
                                               compare_sequence_numbers=False)
     else:
         if not self.is_recovered() or self.stopped:
             raise AuthorityException(Constants.INVALID_ACTOR_STATE)
         self.wrapper.modify_lease_request(reservation=reservation, caller=caller, compare_sequence_numbers=True)
コード例 #8
0
    def check_incoming_close_lease(self, request: ABCAuthorityReservation, incoming: ABCReservationMixin):
        self.assertIsNotNone(incoming)

        rset = incoming.get_resources()

        self.assertIsNotNone(rset)

        self.assertEqual(request.get_requested_units(), rset.get_units())

        uset = rset.get_resources()
        self.assertIsNotNone(uset)
        self.assertEqual(0, uset.get_units())
コード例 #9
0
    def bind(self, *, reservation: ABCAuthorityReservation) -> bool:
        # Simple for now: make sure that this is a valid term and do not modify
        # its start/end time and add it to the calendar. If the request came
        # after its start time, but before its end cycle, add it for allocation
        # to lastAllocatedCycle + 1. If it came after its end cycle, throw.
        current_cycle = self.actor.get_current_cycle()
        approved = reservation.get_requested_term()
        start = self.clock.cycle(when=approved.get_new_start_time())

        if start <= current_cycle:
            end = self.clock.cycle(when=approved.get_end_time())
            if end <= current_cycle:
                self.error(
                    message=
                    "The request cannot be redeemed: its term has expired")
            start = current_cycle + 1

        self.calendar.add_request(reservation=reservation, cycle=start)
        close = self.get_close(term=reservation.get_requested_term())
        self.calendar.add_closing(reservation=reservation, cycle=close)
        return False
コード例 #10
0
    def map(self, *, reservation: ABCAuthorityReservation,
            node_id_to_reservations: dict) -> dict:
        """
        Maps a reservation. Indicates we will approve the request: update its
        expire time in the calendar, and issue a map probe. The map probe will
        result in a retry of the mapper request through bind or extend
        above, which will release the request to the associated mapper.

        @param reservation: the reservation
        @param node_id_to_reservations: node_id_to_reservations
        @throws Exception in case of error
        """
        assigned = self.assign_reservation(
            reservation=reservation,
            node_id_to_reservations=node_id_to_reservations)
        if assigned is not None:
            approved = reservation.get_requested_term()
            reservation.set_approved(term=approved,
                                     approved_resources=assigned)
            reservation.set_bid_pending(value=False)
            node_id = assigned.get_sliver().get_node_map()[1]

            if node_id_to_reservations.get(node_id, None) is None:
                node_id_to_reservations[node_id] = ReservationSet()
            node_id_to_reservations[node_id].add(reservation=reservation)
        else:
            if not reservation.is_terminal():
                self.logger.debug(
                    f"Deferring reservation {reservation} for the next cycle: "
                    f"{self.actor.get_current_cycle() + 1}")
                self.reschedule(reservation=reservation)

        return node_id_to_reservations
コード例 #11
0
    def assign(
            self, *, reservation: ABCAuthorityReservation,
            delegation_name: str, graph_node: BaseSliver,
            existing_reservations: List[ABCReservationMixin]) -> ResourceSet:
        """
        Assign a reservation
        :param reservation: reservation
        :param delegation_name: Name of delegation serving the request
        :param graph_node: ARM Graph Node serving the reservation
        :param existing_reservations: Existing Reservations served by the same ARM node
        :return: ResourceSet with updated sliver annotated with properties
        :raises: AuthorityException in case the request cannot be satisfied
        """
        reservation.set_send_with_deficit(value=True)

        requested = reservation.get_requested_resources().get_sliver()
        self.__dump_sliver(sliver=requested)
        if not isinstance(requested, NetworkServiceSliver):
            raise AuthorityException(
                f"Invalid resource type {requested.get_type()}")

        current = reservation.get_resources()

        resource_type = ResourceType(resource_type=str(requested.get_type()))

        gained = None
        lost = None
        if current is None:
            self.logger.debug("check if sliver can be provisioned")
            # FIXME Add validation to check ticketed sliver against ARM
            # Refer Network Node Control for reference

            self.logger.debug(
                f"Slice properties: {reservation.get_slice().get_config_properties()}"
            )
            unit = Unit(
                rid=reservation.get_reservation_id(),
                slice_id=reservation.get_slice_id(),
                actor_id=self.authority.get_guid(),
                sliver=requested,
                rtype=resource_type,
                properties=reservation.get_slice().get_config_properties())
            gained = UnitSet(plugin=self.authority.get_plugin(),
                             units={unit.reservation_id: unit})
        else:
            # FIXME: handle modify
            self.logger.info(
                f"Extend Lease for now, no modify supported res# {reservation}"
            )
            return current

        result = ResourceSet(gained=gained, lost=lost, rtype=resource_type)
        result.set_sliver(sliver=requested)
        return result
コード例 #12
0
    def do_update_lease(self, *, actor: ABCActorMixin,
                        proxy: ABCControllerCallbackProxy,
                        reservation: ABCAuthorityReservation,
                        update_data: UpdateData, callback: ABCCallbackProxy,
                        caller: AuthToken):
        proxy.get_logger().info(
            "Outbound update lease request from <{}>: {}".format(
                caller.get_name(), reservation))

        state = proxy.prepare_update_lease(reservation=reservation,
                                           update_data=update_data,
                                           callback=callback,
                                           caller=caller)
        state.set_caller(caller=caller)
        state.set_type(rtype=RPCRequestType.UpdateLease)
        rpc = RPCRequest(request=state,
                         actor=actor,
                         proxy=proxy,
                         reservation=reservation,
                         sequence=reservation.get_sequence_out())
        self.enqueue(rpc=rpc)
コード例 #13
0
    def update_lease(self, *, reservation: ABCAuthorityReservation):
        self.validate(reservation=reservation)
        # get a callback to the actor calling update_lease, so that any
        # failures in the remote actor can be delivered back
        callback = Proxy.get_callback(
            actor=reservation.get_actor(),
            protocol=reservation.get_callback().get_type())
        if callback is None:
            raise RPCException(
                message=Constants.NOT_SPECIFIED_PREFIX.format("callback"))

        # Send Update Lease back to Orchestrator
        self.do_update_lease(actor=reservation.get_actor(),
                             proxy=reservation.get_callback(),
                             reservation=reservation,
                             update_data=reservation.get_update_data(),
                             callback=callback,
                             caller=reservation.get_actor().get_identity())

        if reservation.get_broker_callback() is not None:
            # Send Update Lease to Broker
            self.do_update_lease(actor=reservation.get_actor(),
                                 proxy=reservation.get_broker_callback(),
                                 reservation=reservation,
                                 update_data=reservation.get_update_data(),
                                 callback=callback,
                                 caller=reservation.get_actor().get_identity())
コード例 #14
0
    def assign(
            self, *, reservation: ABCAuthorityReservation,
            delegation_name: str, graph_node: BaseSliver,
            existing_reservations: List[ABCReservationMixin]) -> ResourceSet:
        """
        Assign a reservation
        :param reservation: reservation
        :param delegation_name: Name of delegation serving the request
        :param graph_node: ARM Graph Node serving the reservation
        :param existing_reservations: Existing Reservations served by the same ARM node
        :return: ResourceSet with updated sliver annotated with properties
        :raises: AuthorityException in case the request cannot be satisfied
        """

        if graph_node.capacity_delegations is None or reservation is None:
            raise AuthorityException(Constants.INVALID_ARGUMENT)

        delegated_capacities = graph_node.get_capacity_delegations()
        available_delegated_capacity = FimHelper.get_delegation(
            delegated_capacities=delegated_capacities,
            delegation_name=delegation_name)
        if available_delegated_capacity is None:
            raise AuthorityException(
                f"Allocated node {graph_node.node_id} does not have delegation: {delegation_name}"
            )

        reservation.set_send_with_deficit(value=True)

        requested = reservation.get_requested_resources().get_sliver()
        if not isinstance(requested, NodeSliver):
            raise AuthorityException(
                f"Invalid resource type {requested.get_type()}")

        current = reservation.get_resources()

        resource_type = ResourceType(resource_type=str(requested.get_type()))

        gained = None
        lost = None
        if current is None:
            # Check if Capacities can be satisfied by Delegated Capacities
            self.__check_capacities(
                rid=reservation.get_reservation_id(),
                requested_capacities=requested.get_capacity_allocations(),
                available_capacities=available_delegated_capacity,
                existing_reservations=existing_reservations)

            # Check if Capacities can be satisfied by Capacities
            self.__check_capacities(
                rid=reservation.get_reservation_id(),
                requested_capacities=requested.get_capacity_allocations(),
                available_capacities=graph_node.get_capacities(),
                existing_reservations=existing_reservations)

            # Check components
            # Check if Components can be allocated
            if requested.attached_components_info is not None:
                self.__check_components(
                    rid=reservation.get_reservation_id(),
                    requested_components=requested.attached_components_info,
                    graph_node=graph_node,
                    existing_reservations=existing_reservations)

            self.logger.debug(
                f"Slice properties: {reservation.get_slice().get_config_properties()}"
            )
            unit = Unit(
                rid=reservation.get_reservation_id(),
                slice_id=reservation.get_slice_id(),
                actor_id=self.authority.get_guid(),
                sliver=requested,
                rtype=resource_type,
                properties=reservation.get_slice().get_config_properties())
            gained = UnitSet(plugin=self.authority.get_plugin(),
                             units={unit.reservation_id: unit})
        else:
            # FIX ME: handle modify
            self.logger.info(
                f"Extend Lease for now, no modify supported res# {reservation}"
            )
            return current

        result = ResourceSet(gained=gained, lost=lost, rtype=resource_type)
        result.set_sliver(sliver=requested)
        return result
コード例 #15
0
    def correct_deficit(self, *, reservation: ABCAuthorityReservation):
        if reservation.get_resources() is None:
            return

        self.finish_correct_deficit(reservation=reservation)
コード例 #16
0
    def assign_reservation(self, *, reservation: ABCAuthorityReservation,
                           node_id_to_reservations: dict):
        """
        Assign resources for the given reservation

        @params reservation the request
        @params node_id_to_reservations node_id_to_reservations
        @returns a set of resources for the request
        @raises Exception in case of error
        """
        requested = reservation.get_requested_resources()
        rtype = requested.get_type()
        rc = self.get_control_by_type(rtype=rtype)
        if rc is not None:
            try:
                ticketed_sliver = requested.get_sliver()
                node_id = ticketed_sliver.get_node_map()[1]
                self.logger.debug(
                    f"node_id {node_id} serving reservation# {reservation}")
                if node_id is None:
                    raise AuthorityException(
                        f"Unable to find node_id {node_id} for reservation# {reservation}"
                    )

                graph_node = None
                if isinstance(ticketed_sliver, NodeSliver):
                    graph_node = self.get_network_node_from_graph(
                        node_id=node_id)

                elif isinstance(ticketed_sliver, NetworkServiceSliver):
                    graph_node = self.get_network_service_from_graph(
                        node_id=node_id)

                else:
                    msg = f'Reservation {reservation} sliver type is neither Node, nor NetworkServiceSliver'
                    self.logger.error(msg)
                    raise AuthorityException(msg)

                self.logger.debug(
                    f"Node {graph_node} serving reservation# {reservation}")

                existing_reservations = self.get_existing_reservations(
                    node_id=node_id,
                    node_id_to_reservations=node_id_to_reservations)

                delegation_name, broker_callback = self.get_delegation_name_and_callback(
                    delegation_id=requested.get_resources().get_delegation_id(
                    ))

                rset = rc.assign(reservation=reservation,
                                 delegation_name=delegation_name,
                                 graph_node=graph_node,
                                 existing_reservations=existing_reservations)

                if rset is None or rset.get_sliver(
                ) is None or rset.get_sliver().get_node_map() is None:
                    raise AuthorityException(
                        f"Could not assign resources to reservation# {reservation}"
                    )

                reservation.set_broker_callback(
                    broker_callback=broker_callback)
                return rset
            except Exception as e:
                self.logger.error(traceback.format_exc())
                self.logger.error(f"Could not assign {e}")
                return None
        else:
            raise AuthorityException(
                Constants.UNSUPPORTED_RESOURCE_TYPE.format(
                    reservation.get_type()))