Ejemplo n.º 1
0
    def on_modified(self, _):
        """Callback invoked when the file is modified

        This captures all other modification events that occur against the file
        """
        if self.modify_event:
            publish(self.modify_event)
Ejemplo n.º 2
0
    def post(self):
        """
        ---
        summary: Publish a new event
        parameters:
          - name: bg-namespace
            in: header
            required: false
            description: Namespace to use
            type: string
          - name: event
            in: body
            description: The the Event object
            schema:
              $ref: '#/definitions/Event'
        responses:
          204:
            description: An Event has been published
          400:
            $ref: '#/definitions/400Error'
          50x:
            $ref: '#/definitions/50xError'
        tags:
          - Event
        """
        publish(SchemaParser.parse_event(self.request.decoded_body, from_string=True))

        self.set_status(204)
Ejemplo n.º 3
0
    def on_moved(self, _):
        """Callback invoked when the file is moved

        This captures if the file is moved into or from the directory
        """
        if self.moved_event:
            publish(self.moved_event)
Ejemplo n.º 4
0
async def shutdown():
    """Do shutdown things

    This still operates within the ioloop, so stopping it should be the last
    thing done.

    Because things in startup aren't guaranteed to have been run we need to be
    careful about checking to make sure things actually need to be shut down.

    This execution is normally scheduled by the signal handler.
    """

    logger.debug("Stopping server for new HTTP connections")
    server.stop()

    logger.debug("Stopping forward processing")
    beer_garden.router.forward_processor.stop()

    # This will almost definitely not be published to the websocket, because it would
    # need to make it up to the main process and back down into this process. We just
    # publish this here in case the main process is looking for it.
    publish(
        Event(name=Events.ENTRY_STOPPED.name, metadata={"entry_point_type": "HTTP"})
    )

    # We need to do this before the scheduler shuts down completely in order to kick any
    # currently waiting request creations
    logger.debug("Closing all open HTTP connections")
    await server.close_all_connections()

    logger.debug("Stopping IO loop")
    io_loop.add_callback(io_loop.stop)
Ejemplo n.º 5
0
    def on_deleted(self, _):
        """Callback invoked when the file is deleted

        This captures if the file was deleted (be warned that VIM does this by
        default during write actions)
        """
        if self.deleted_event:
            publish(self.deleted_event)
Ejemplo n.º 6
0
    def on_created(self, _):
        """Callback invoked when the file is created

        When a user VIM edits a file it DELETES, then CREATES the file, this
        captures that case
        """
        if self.create_event:
            publish(self.create_event)
Ejemplo n.º 7
0
def run(ep_conn):
    conn_manager = StompManager(ep_conn)

    _setup_event_handling(conn_manager)
    _setup_operation_forwarding()

    entry_config = config.get("entry.stomp")
    parent_config = config.get("parent.stomp")
    garden_name = config.get("garden.name")

    if entry_config.get("enabled"):
        conn_manager.add_connection(stomp_config=entry_config,
                                    name=f"{garden_name}_entry",
                                    is_main=True)

    if parent_config.get("enabled"):
        conn_manager.add_connection(stomp_config=parent_config,
                                    name=f"{garden_name}_parent",
                                    is_main=True)

    for garden in get_gardens(include_local=False):
        if garden.name != garden_name and garden.connection_type:
            if garden.connection_type.casefold() == "stomp":
                connection_params = garden.connection_params.get("stomp", {})
                connection_params["send_destination"] = None
                conn_manager.add_connection(stomp_config=connection_params,
                                            name=garden.name)

    conn_manager.start()

    logger.info("Stomp entry point started")

    publish(
        Event(name=Events.ENTRY_STARTED.name,
              metadata={"entry_point_type": "STOMP"}))

    while not shutdown_event.wait(10):
        for name, info in conn_manager.conn_dict.items():
            connection = info.get("conn")

            if connection:
                logger.debug(f"{name}: Checking connection")
                if not connection.is_connected():
                    logger.debug(f"{name}: Attempting to reconnect")

                    if connection.connect():
                        logger.debug(f"{name}: Reconnect successful")
                    else:
                        logger.debug(f"{name}: Reconnect failed")

    conn_manager.shutdown()
    conn_manager.stop()
    conn_manager.join(5)

    logger.debug("Stopping forward processing")
    beer_garden.router.forward_processor.stop()
Ejemplo n.º 8
0
def rescan(*args, **kwargs) -> List[Runner]:
    """Scans plugin directory and starts any new runners"""
    new_runners = lpm_proxy.scan_path(*args, **kwargs)

    for runner in new_runners:
        publish(
            Event(
                name=Events.RUNNER_STARTED.name,
                payload_type=Runner.__name__,
                payload=runner,
            )
        )

    return new_runners
Ejemplo n.º 9
0
    def shutdown(self):
        self.logger.debug("Disconnecting connections")
        for value in self.conn_dict.values():
            value["conn"].disconnect()

        # This will almost definitely not be published because
        # it would need to make it up to the main process and
        # back down into this process. We just publish this
        # here in case the main process is looking for it.
        publish(
            Event(
                name=Events.ENTRY_STOPPED.name,
                metadata={"entry_point_type": "STOMP"},
            ), )
Ejemplo n.º 10
0
async def startup():
    """Do startup things.

    This is the first thing called from within the ioloop context.
    """
    global anonymous_principal

    http_config = config.get("entry.http")
    logger.debug(
        f"Starting HTTP server on {http_config.host}:{http_config.port}")
    server.listen(http_config.port, http_config.host)

    logger.info("Http entry point started")

    publish(
        Event(name=Events.ENTRY_STARTED.name,
              metadata={"entry_point_type": "HTTP"}))
Ejemplo n.º 11
0
def _publish_failed_forward(operation: Operation = None,
                            error_message: str = None,
                            event_name: str = None):
    if operation.operation_type == "REQUEST_CREATE":
        complete_request(
            operation.model.id,
            status="ERROR",
            output=error_message,
            error_class=event_name,
        )

    publish(
        Event(
            name=event_name,
            payload_type="Operation",
            payload=operation,
            error_message=error_message,
        ))

    raise RoutingRequestException(error_message)
Ejemplo n.º 12
0
async def startup():
    """Do startup things.

    This is the first thing called from within the ioloop context.
    """
    global anonymous_principal

    # Need to wait until after mongo connection established to load
    anonymous_principal = load_anonymous()

    http_config = config.get("entry.http")
    logger.debug(f"Starting HTTP server on {http_config.host}:{http_config.port}")
    server.listen(http_config.port, http_config.host)

    logger.debug("Starting forward processor")
    beer_garden.router.forward_processor.start()

    beer_garden.api.http.logger.info("Http entry point is started. Hello!")

    publish(
        Event(name=Events.ENTRY_STARTED.name, metadata={"entry_point_type": "HTTP"})
    )
Ejemplo n.º 13
0
def rescan(*args, **kwargs) -> List[Runner]:
    """Scan plugin directory and start any new runners.

    Args:
        *args: Arguments to pass to ``scan_path`` in the PluginManager object.
        **kwargs: Keyword arguments to pass to ``scan_path`` in the PluginManager
            object.

    Returns:
        A list of the new runners
    """
    new_runners = lpm_proxy.scan_path(*args, **kwargs)

    for the_runner in new_runners:
        publish(
            Event(
                name=Events.RUNNER_STARTED.name,
                payload_type=Runner.__name__,
                payload=the_runner,
            ))

    return new_runners
Ejemplo n.º 14
0
def forward(operation: Operation):
    """Forward the operation to a child garden

    Intended to be called in the context of an executor or processor.

    Args:
        operation: The operation to forward

    Returns:
        The result of the specific forward transport function used

    Raises:
        RoutingRequestException: Could not determine a route to child
        UnknownGardenException: The specified target garden is unknown
    """
    target_garden = gardens.get(operation.target_garden_name)

    if not target_garden:
        target_garden = get_garden(operation.target_garden_name)

    try:
        if not target_garden:
            raise UnknownGardenException(
                f"Unknown child garden {operation.target_garden_name}")

        if not target_garden.connection_type:
            raise RoutingRequestException(
                "Attempted to forward operation to garden "
                f"'{operation.target_garden_name}' but the connection type was None. "
                "This probably means that the connection to the child garden has not "
                "been configured.")

        if target_garden.connection_type.casefold() == "http":
            return _forward_http(operation, target_garden)
        elif target_garden.connection_type.casefold() == "stomp":
            return _forward_stomp(operation, target_garden)
        else:
            raise RoutingRequestException(
                f"Unknown connection type {target_garden.connection_type}")

    except ForwardException as ex:
        error_message = str(ex)
        operation = ex.operation

        if operation.operation_type == "REQUEST_CREATE":
            complete_request(
                operation.model.id,
                status="ERROR",
                output=error_message,
                error_class=ex.event_name,
            )

        # Publish an event
        publish(
            Event(
                name=ex.event_name,
                payload_type="Operation",
                payload=operation,
                error_message=error_message,
            ))

        raise
Ejemplo n.º 15
0
def handle_event(event):
    """Handle garden-related events

    For GARDEN events we only care about events originating from downstream. We also
    only care about immediate children, not grandchildren.

    Whenever a garden event is detected we should update that garden's database
    representation.

    This method should NOT update the routing module. Let its handler worry about that!
    """
    if event.garden != config.get("garden.name"):

        if event.name in (
                Events.GARDEN_STARTED.name,
                Events.GARDEN_UPDATED.name,
                Events.GARDEN_STOPPED.name,
                Events.GARDEN_SYNC.name,
        ):
            # Only do stuff for direct children
            if event.payload.name == event.garden:
                try:
                    existing_garden = get_garden(event.payload.name)
                except DoesNotExist:
                    existing_garden = None

                for system in event.payload.systems:
                    system.local = False

                if existing_garden is None:
                    event.payload.connection_type = None
                    event.payload.connection_params = {}

                    garden = create_garden(event.payload)
                else:
                    for attr in ("status", "status_info", "namespaces",
                                 "systems"):
                        setattr(existing_garden, attr,
                                getattr(event.payload, attr))

                    garden = update_garden(existing_garden)

                # Publish update events for UI to dynamically load changes for Systems
                for system in garden.systems:
                    publish(
                        Event(
                            name=Events.SYSTEM_UPDATED.name,
                            garden=event.garden,
                            payload_type="System",
                            payload=system,
                        ))

    elif event.name == Events.GARDEN_UNREACHABLE.name:
        target_garden = get_garden(event.payload.target_garden_name)

        if target_garden.status not in [
                "UNREACHABLE",
                "STOPPED",
                "BLOCKED",
                "ERROR",
        ]:
            update_garden_status(event.payload.target_garden_name,
                                 "UNREACHABLE")
    elif event.name == Events.GARDEN_ERROR.name:
        target_garden = get_garden(event.payload.target_garden_name)

        if target_garden.status not in [
                "UNREACHABLE",
                "STOPPED",
                "BLOCKED",
                "ERROR",
        ]:
            update_garden_status(event.payload.target_garden_name, "ERROR")
    elif event.name == Events.GARDEN_NOT_CONFIGURED.name:
        target_garden = get_garden(event.payload.target_garden_name)

        if target_garden.status == "NOT_CONFIGURED":
            update_garden_status(event.payload.target_garden_name,
                                 "NOT_CONFIGURED")