Skip to content
cli.py 36.8 KiB
Newer Older
        self.client.check('forward', query='id=%s' % login)
        # Create the tunnel to the node:
        try:
            host_client = self.server.get_client(login)
        except KeyError:
            raise KeyError('Specified client is not connected')
        s2n_tun = host_client.forward(port, destination)

        # Create tunnel to the CLI
        self.client.register_tunnel('forward', host_client, s2n_tun)

    @listed
    def dbstats(self):
        """ Get statistics about tql database.
        """
        return self.server.db.stats()

    def forward_call(self, login, func, *args, **kwargs):
        """ Forward a call to a connected client and return result.

        :param login: login of the connected client
        :param func: function to execute on the client
        :param \*args, \*\*kwargs: arguments of the call
        """
        self.client.check('forward_call')
        client = self.server.get_client(login)
        return client.conn.call(func, *args, **kwargs)


class CliClient(Client):

    """ A cli client connected to the cc-server.
    """

    ROLE = 'cli'
    RPC_HANDLER = CliHandler
    KILL_ALREADY_CONNECTED = True
    def __init__(self, *args, **kwargs):
        super(CliClient, self).__init__(*args, **kwargs)
        self._tunnels = {}  # Running tunnels for this client (as client)

    def spawn_job(self, job_class, **kwargs):
        self._server.jobs.spawn(job_class, self.login, **kwargs)

    def register_tunnel(self, ttype, client, tun, label=None):
        """ Create and register a tunnel for this client.

        :param ttype: type of tunnel
        :param client: client where the tunnel go
        :param tun: the tunnel of this client
        :param label: label of the tunnel to create
        """
        def cb_on_close(tun):
            # Call the default callback:
            tun.cb_default_on_close(tun)
            # Delete the tunnel from the current running tunnels:
            self.unregister_tunnel(tun.label)

        ctun = self.conn.create_tunnel(label=label, endpoint=tun.socket,
                                       on_close=cb_on_close)
        self._tunnels[ctun.label] = (ttype, client, ctun, tun)
        return ctun

    def get_tunnel(self, label):
        """ Get the tunnel binded to the provided label.

        :return: a tuple (type, remote_client, tunnel, remote_client_tunnel)
            where: **type** is a string provided on tunnel creation,
            **remote_client** the client object of the remote client on which
            the tunnel is established, **tunnel** the cli-to-server tunnel
            object from the sjRpc, **remote_client_tunnel** the
            server-to-remote-client tunnel object from the sjRpc.
        """
        return self._tunnels[label]

    def unregister_tunnel(self, label):
        try:
            del self._tunnels[label]
        except KeyError:
            pass

Client.register_client_class(CliClient)