Commit d07fca36 authored by Sébastien Luttringer's avatar Sébastien Luttringer
Browse files

Implement port forwarding commands

parent 5d3d08bf
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -28,6 +28,7 @@ class Cli(object):
        self.rpc = None
        self.aliases = Aliases()
        self.tagdisplay = TagDisplay()
        self.forwards = {}
        self.prompt = ""

    def start(self, line=""):
+1 −3
Original line number Diff line number Diff line
@@ -4,15 +4,13 @@
'''
CloudControl CLI command module
'''

import re
import ConfigParser
import os
import shlex
import imp
import sys
import termios
import threading
import tty

from cccli.exception import *
from sjrpc.core import RpcError
+62 −0
Original line number Diff line number Diff line
#!/usr/bin/env python
#coding=utf8

'''
CloudControl addforward command
'''

from cccli.command import TqlCommand
from cccli.tunnel import Forward
from cccli.exception import *

class Command_addforward(TqlCommand):
    '''Create a forward'''

    def __init__(self, cli, argv0):
        TqlCommand.__init__(self, cli, argv0)
        self.tql_filter += "&con&r~'host|hv'"
        self.remove_option("--quiet")
        self.remove_option("--direct")
        self.add_option("-s", "--source", default="127.0.0.1",
                        help="Tunnel local source ip address. "
                        "Default 127.0.0.1")
        self.add_option("-d", "--destination", default="127.0.0.1:22",
                        help="Tunnel remote destination ip address. "
                        "Default 127.0.0.1")

    def __call__(self, argv):
        # argv check
        self.parse_args(argv)
        if len(self.args) != 1:
            raise cmdBadArgument()
        # checking source info
        splitted_source = map(str.strip, self.options.source.split(":"))
        self.source_ip = splitted_source[0]
        if len(splitted_source) == 1 or splitted_source[1] == "":
            self.source_port = 0
        else:
            self.source_port = int(splitted_source[1])
        # checking dest info
        splitted_dest = map(str.strip, self.options.destination.split(":"))
        self.dest_ip = splitted_dest[0]
        if len(splitted_dest) == 1 or splitted_dest[1] == "":
            self.dest_port = 0
        else:
            self.dest_port = int(splitted_dest[1])
        # list using method forward to check rights
        ans = self.rpccall("list", self.args[0], method="forward",
                           _direct=True, _status=False)
        for obj in ans["objects"]:
            # Create forward object
            fwd = Forward(self.rpc, obj["id"],
                          self.source_ip, self.source_port,
                          self.dest_ip, self.dest_port)
            # register it into cli
            self.cli.forwards[fwd.id] = fwd
            # start it
            fwd.start()
            # print
            self.cli.printer.out("Forward %s added." % fwd.id)

    def remote_functions(self):
        return set(("list", "forward"))
+30 −0
Original line number Diff line number Diff line
#!/usr/bin/env python
#coding=utf8

'''
CloudControl delforward command
'''

from cccli.command import Command
from cccli.exception import *

class Command_delforward(Command):
    '''Delete forwarded connection'''

    def __init__(self, cli, argv0):
        Command.__init__(self, cli, argv0)

    def __call__(self, argv):
        # argv check
        if len(argv) < 2:
            raise cmdBadArgument()
        for fwd_id in argv[1:]:
            if fwd_id in self.cli.forwards:
                self.printer.out("Closing %s" % fwd_id)
                self.cli.forwards[fwd_id].stop()
                del self.cli.forwards[fwd_id]
            else:
                self.printer.warn("No such forward: %s" % fwd_id)

    def usage(self):
        return "Usage: delforward <tunnel id> [tunnel id]..."
+36 −0
Original line number Diff line number Diff line
#!/usr/bin/env python
#coding=utf8

'''
CloudControl forwards command
'''

from cccli.command import Command
from cccli.printer import color
from cccli.exception import *

class Command_forwards(Command):
    '''List open forwards'''

    def __init__(self, cli, argv0):
        Command.__init__(self, cli, argv0)

    def __call__(self, argv):
        # argv check
        if len(argv) != 1:
            raise cmdBadArgument()
        out = self.printer.out
        for fwd in self.cli.forwards.values():
            out("Forward: %s%s%s" % (color["lpurple"], fwd.id, color["reset"]))
            out("  HostID: %s" % fwd.host_id)
            out("  Local socket: %s %s" % (fwd.source_ip, fwd.source_port))
            out("  Remote socket: %s %s" % (fwd.dest_ip, fwd.dest_port))
            out("  Tunnels:")
            out("    count: %s" % len(fwd.tunnels))
            for label, tun in fwd.tunnels.items():
                remote_ip, remote_port = tun.endpoint.getpeername()
                out("    label: %s, remote ip: %s, remote port: %s"
                    % (label, remote_ip, remote_port))
        out("Forward count: %d, Tunnels count: %d" %
            (len(self.cli.forwards),
             sum(len(f.tunnels) for f in self.cli.forwards.values())))
Loading