Пример #1
0
    def from_external_config_file(cls,
                                  path,
                                  instance_type,
                                  environment=DEFAULT_ENVIRONMENT,
                                  system_folders=False):
        instance_name = Path(path).stem

        self_ = cls.__new__(cls)
        self_.name = instance_name
        self_.scope = "system" if system_folders else "user"
        self_.config_dir = Path(path).parent
        self_.config_file = path
        self_.environment = environment
        self_.set_folders(instance_type, instance_name, system_folders)
        module_name = logger_name(__name__)
        self_.log = logging.getLogger(module_name)
        if self_.LOGGING_ENABLED:
            self_.setup_logging()
        self_.log.debug("Test!")
        return self_
Пример #2
0
 def __init__(self):
     """Create a new CryptorBase instance."""
     self.log = logging.getLogger(logger_name(__name__))
Пример #3
0
# -*- coding: utf-8 -*-
import logging

from http import HTTPStatus
from flasgger import swag_from
from pathlib import Path

from vantage6.server.resource import (with_user, ServicesResources)
from vantage6.common import logger_name
from vantage6.server.model import Rule as db_Rule
from vantage6.server.resource._schema import RuleSchema

module_name = logger_name(__name__)
log = logging.getLogger(module_name)


def setup(api, api_base, services):

    path = "/".join([api_base, module_name])
    log.info(f'Setting up "{path}" and subdirectories')

    api.add_resource(Rule,
                     path,
                     endpoint='rule_without_id',
                     methods=('GET', ),
                     resource_class_kwargs=services)
    api.add_resource(Rule,
                     path + '/<int:id>',
                     endpoint='rule_with_id',
                     methods=('GET', ),
                     resource_class_kwargs=services)
Пример #4
0
# -*- coding: utf-8 -*-
import logging
import base64

from marshmallow import fields
from marshmallow_sqlalchemy import ModelSchema
from flask import url_for

from vantage6.server import db
from vantage6.common import logger_name
from vantage6.common.globals import STRING_ENCODING

log = logging.getLogger(logger_name(__name__))


class HATEOASModelSchema(ModelSchema):
    """Convert foreign-key fields to HATEOAS specification."""

    api = None

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)

        # to one relationship
        setattr(self, "node", lambda obj: self.hateos("node", obj))
        setattr(self, "organization",
                lambda obj: self.hateos("organization", obj))
        setattr(self, "collaboration",
                lambda obj: self.hateos("collaboration", obj))
        setattr(self, "user", lambda obj: self.hateos("user", obj))
        setattr(self, "result", lambda obj: self.hateos("result", obj))
Пример #5
0
class DefaultSocketNamespace(Namespace):
    """
    Handlers for SocketIO events are different than handlers for routes and
    that introduces a lot of confusion around what can and cannot be done in a
    SocketIO handler. The main difference is that all the SocketIO events
    generated for a client occur in the context of a single long running
    request.
    """

    log = logging.getLogger(logger_name(__name__))

    def on_connect(self):
        """
        A new incomming connection request from a client.

        New incomming connections are authenticated using their
        JWT authorization token which is obtained from the REST api.
        A session is created for each connected clients which lives
        as long as the connection is active. There has not been made
        any difference between connecting and re-connecting.
        """

        self.log.info(f'Client connected: "{request.sid}"')

        # try to catch jwt authorization token.
        try:
            verify_jwt_in_request()

        except jwt.exceptions.ExpiredSignatureError:
            self.log.error("JWT has expired")
            emit("expired_token", "", room=request.sid)

        except Exception as e:
            self.log.error(
                "Could not connect client! No or Invalid JWT token?")
            self.log.exception(e)
            session.name = "no-sure-yet"
            self.__join_room_and_notify(request.sid)

            # FIXME: expired probably doesn't cover it ...
            emit("expired_token", "", room=request.sid)
            return

        # get identity from token.
        user_or_node_id = get_jwt_identity()
        session.auth = auth = db.Authenticatable.get(user_or_node_id)
        session.auth.status = 'online'
        session.auth.save()

        # It appears to be necessary to use the root socketio instance
        # otherwise events cannot be sent outside the current namespace.
        # In this case, only events to '/tasks' can be emitted otherwise.
        server.socketio.emit('node-status-changed', namespace='/admin')

        # define socket-session variables.
        session.type = auth.type
        session.name = auth.username if session.type == 'user' else auth.name
        self.log.info(
            f'Client identified as <{session.type}>: <{session.name}>')

        # join appropiate rooms, nodes join a specific collaboration room.
        # users do not belong to specific collaborations.
        session.rooms = ['all_connections', 'all_' + session.type + 's']

        if session.type == 'node':
            session.rooms.append('collaboration_' + str(auth.collaboration_id))
            session.rooms.append('node_' + str(auth.id))
        elif session.type == 'user':
            session.rooms.append('user_' + str(auth.id))

        for room in session.rooms:
            self.__join_room_and_notify(room)

    def on_disconnect(self):
        """
        Client that disconnects needs to leave all rooms.
        """
        for room in session.rooms:
            # self.__leave_room_and_notify(room)
            self.__leave_room_and_notify(room)

        session.auth.status = 'offline'
        session.auth.save()

        # It appears to be necessary to use the root socketio instance
        # otherwise events cannot be sent outside the current namespace.
        # In this case, only events to '/tasks' can be emitted otherwise.
        self.log.warning('emitting to /admin')
        server.socketio.emit('node-status-changed', namespace='/admin')

        self.log.info(f'{session.name} disconnected')

    def on_message(self, message: str):
        """
        An incomming message from any client.

        Parameters
        ----------
        message : str
            message that is going to be displayed in the server-log
        """
        self.log.info('received message: ' + message)

    def on_error(self, e: str):
        """
        An incomming error from any of the client.

        Parameters
        ----------
        e : str
            error message that is being displayed in the server log
        """
        self.log.error(e)

    def on_join_room(self, room: str):
        """
        Let clients join any room they like by specifying the name.

        Parameters
        ----------
        room : str
            name of the room the client wants to join
        """
        self.__join_room_and_notify(room)

    def on_container_failed(self, node_id: int, status_code: int,
                            result_id: int, collaboration_id: int):
        """
        An algorithm container has crashed at a node.

        This event notifies all nodes, and users that a container has crashed
        in their collaboration.

        Parameters
        ----------
        node_id : int
            node_id where the algorithm container was running
        status_code : int
            status code from the container
        result_id : int
            result_id for which the container was running
        collaboration_id : int
            collaboration for which the task was running
        """
        # obtain run id,
        run_id = db.Result.get(result_id).task.run_id

        self.log.critical(
            f"A container in for run_id={run_id} and result_id={result_id}"
            f" within collaboration_id={collaboration_id} on node_id={node_id}"
            f" exited with status_code={status_code}.")

        room = "collaboration_" + str(collaboration_id)
        emit("container_failed", run_id, room=room)

    def __join_room_and_notify(self, room: str):
        """
        Joins room and notify other clients in this room.

        Parameters
        ----------
        room : str
            name of the room the client want to join
        """
        join_room(room)
        msg = f'<{session.name}> joined room <{room}>'
        self.log.info(msg)
        emit('message', msg, room=room)

    def __leave_room_and_notify(self, room: str):
        """
        Leave room and notify other clients in this room.

        Parameters
        ----------
        room : str
            name of the room the client is leaving
        """
        leave_room(room)
        msg = f'{session.name} left room {room}'
        self.log.info(msg)
        emit('message', msg, room=room)

    # TODO: to be removed in version 2.x.x. nodes 1.1.0 dont use this anymore.
    def on_ping(self, node_id):
        # self.log.debug(f"ping from id={node_id}")
        room = f"node_{node_id}"
        emit("pang", "success!", room=room)
Пример #6
0
import logging
import re
import docker
import requests
import base64
import json

from dateutil.parser import parse
from requests.api import request

from vantage6.common import logger_name
from vantage6.common import ClickLogger

logger = logger_name(__name__)
log = logging.getLogger(logger)

docker_client = docker.from_env()


def registry_basic_auth_header(docker_client, registry):
    """Obtain credentials for registry

    This is a wrapper around docker-py to obtain the credentials used
    to access a registry. Normally communication to the registry goes
    through the Docker deamon API (locally), therefore we have to take
    extra steps in order to communicate with the (Harbor) registry
    directly.

    Note that this has only been tested for the harbor registries.

    Parameters