Example #1
0
 def test_bind_client_ipv6(self):
     """IPv6 client binding"""
     q1 = QoS("100M", "My first QoS")
     i1 = Interface("LAN", "My second interface", {'qos1': q1})
     r = Router("eth0", interfaces={'eth1': i1 })
     r.bind("2001:db8::1", "eth1", "qos1")
     r.bind("2001:db8::2", "eth1", "qos1")
     self.assertEqual(r.clients["2001:db8::1"], ('eth1', 'qos1'))
     self.assertEqual(r.clients["2001:db8::2"], ('eth1', 'qos1'))
Example #2
0
 def test_equality(self):
     """Test equality of two routers"""
     q1 = QoS("100M", "My first QoS")
     q2 = QoS("10M", "My second QoS")
     i1 = Interface("LAN", "My second interface", {'qos1': q1, 'qos2': q2})
     i2 = Interface("WAN", "My third interface", {'qos1': q1})
     r = Router("eth0", interfaces={'eth1': i1, 'eth2': i2})
     self.assertEqual(r, Router("eth0", interfaces={
                 'eth1': Interface("LAN", "My second interface",
                                   {'qos1': QoS("100M", "My first QoS"),
                                    'qos2': q2}),
                 'eth2': Interface("WAN", "My third interface", {'qos1': q1})
                 }))
     self.assertNotEqual(r, Router("eth0",
                                   interfaces={
                 'eth1': Interface("LAN", "My second interface",
                                   {'qos1': QoS("100M", "My first QoS"),
                                    'qos2': q2}),
                 'eth3': Interface("WAN", "My third interface", {'qos1': q1})
                 }))
     self.assertNotEqual(r, Router("eth0", interfaces={
                 'eth1': Interface("LAN", "My second interface",
                                   {'qos3': QoS("3G", "My first QoS"), 'qos2': q2}),
                 'eth2': Interface("WAN", "My third interface", {'qos1': q1})
                 }))
     self.assertNotEqual(r, Router("eth0"))
     self.assertNotEqual(r, "eth0")
     # With equality, clients are not considered
     r.bind("192.168.15.3", "eth2", "qos1")
     self.assertEqual(r, Router("eth0", interfaces={
                 'eth1': Interface("LAN", "My second interface",
                                   {'qos1': QoS("100M", "My first QoS"),
                                    'qos2': q2}),
                 'eth2': Interface("WAN", "My third interface", {'qos1': q1})
                 }))
Example #3
0
 def test_pickle(self):
     """Pickling"""
     q1 = QoS("100M", "My first QoS")
     q2 = QoS("10M", "My second QoS")
     i1 = Interface("LAN", "My second interface", {'qos1': q1, 'qos2': q2})
     i2 = Interface("WAN", "My third interface", {'qos1': q1})
     r = Router("eth0", interfaces={'eth1': i1, 'eth2': i2})
     self.assertEqual(r, pickle.loads(pickle.dumps(r)))
     self.assertEqual(r.clients, pickle.loads(pickle.dumps(r)).clients)
     r.bind("192.168.15.2", "eth2", "qos1")
     self.assertEqual(r, pickle.loads(pickle.dumps(r)))
     self.assertEqual(r.clients, pickle.loads(pickle.dumps(r)).clients)
Example #4
0
 def setUp(self):
     r = Router.load({'clients': 'eth0'})
     # Start the service
     self.service = Service({}, r)
     time.sleep(0.2)         # Safety
     # Configure app
     configure(app)
Example #5
0
 def realSetup(self):
     self.router = Router.load(self.config)
     # Start the service in a separate process
     self.service = Service(
         dict(helper=dict(save=os.path.join(self.temp, "save.pickle"))),
         self.router)
     time.sleep(0.2)  # Safety
Example #6
0
    def setUp(self):
        r = Router.load(yaml.load("""
clients: eth0
interfaces:
  eth1:
    name: LAN
    description: "My first interface"
    qos:
      - qos1
      - qos2
  eth2:
    name: WAN
    description: "My second interface"
    password: 1234
    qos:
      - qos1
qos:
  qos1:
    name: 100M
    description: "My first QoS"
    bandwidth: 100mbps
    netem: delay 100ms 10ms distribution experimental
  qos2:
    name: 10M
    description: "My second QoS"
    bandwidth: 10mbps
    netem: delay 200ms 10ms
"""))
        self.service = Service({}, r) # helper
        configure(app, dict(web=dict(expire=2)))
        self.app = app.test_client() # web
        time.sleep(0.1)
Example #7
0
 def setUp(self):
     r = Router.load({'clients': 'eth0'})
     # Start the service
     self.service = Service({}, r)
     time.sleep(0.2)  # Safety
     # Configure app
     configure(app)
Example #8
0
    def run(cls, args=sys.argv[1:], binder=None):
        """Start the helper service.

        This method should be used to instantiate
        :class:`Service`. The configuration file must be provided as
        an argument.

        :param args: list of command line arguments
        :type args: list of strings
        :param binder: binder to register to the router
        """
        from optparse import OptionParser

        usage = "usage: %prog [options] config.yaml"
        parser = OptionParser(usage=usage)
        parser.add_option("-l", "--log", type="string", dest="log", help="log to file", metavar="FILE")
        parser.add_option("-s", "--syslog", action="store_true", dest="syslog", help="log to syslog")
        parser.add_option("-d", "--debug", action="count", dest="debug", help="enable debugging")
        (options, args) = parser.parse_args(args)
        if len(args) != 1:
            parser.error("incorrect number of arguments")

        # Logger configuration
        l = logging.root
        if options.debug == 1:
            l.setLevel(logging.INFO)
        if options.debug > 1:
            l.setLevel(logging.DEBUG)
        if options.log:
            fh = logging.FileHandler(options.log)
            fh.setFormatter(logging.Formatter("%(asctime)s %(name)s[%(process)d] " "%(levelname)s: %(message)s"))
            l.addHandler(fh)
        if options.syslog:
            sh = logging.handlers.SysLogHandler(address="/dev/log", facility="daemon")
            sh.setFormatter(logging.Formatter("kitero[%(process)d]: " "%(levelname)s %(message)s"))
            l.addHandler(sh)
        if not options.syslog and not options.log:
            # Log to stderr
            eh = logging.StreamHandler()
            eh.setFormatter(logging.Formatter("%(asctime)s %(name)s[%(process)d] " "%(levelname)s: %(message)s"))
            l.addHandler(eh)

        # Reading configuration file
        logger.info("read configuration file %r" % args[0])
        try:
            config = yaml.safe_load(file(args[0]))
            config = kitero.config.merge(config)
            # Create the router
            router = Router.load(config["router"])
            # Add the regular binder to it
            if binder is not None:
                router.register(binder)
            # Start service
            s = cls(config, router)
            s.wait()
        except Exception as e:
            logger.exception("unhandled error received")
            sys.exit(1)
        sys.exit(0)
Example #9
0
    def test_load_with_missing(self):
        """Load router with missing information"""
        doc = """
interfaces:
  eth1:
    description: "My first interface"
"""
        with self.assertRaises(ValueError):
            r = Router.load(yaml.load(doc))
Example #10
0
    def test_load_minimal(self):
        """Load router with minimal information"""
        doc = """
clients: eth0
"""
        r = Router.load(yaml.load(doc))
        self.assertEqual(r.interfaces, {})
        self.assertEqual(r.incoming, ["eth0"])
        self.assertEqual(r.clients, {})
Example #11
0
    def test_load(self):
        """Load router from YAML representation"""
        doc = """
clients: eth0
interfaces:
  eth1:
    name: LAN
    description: "My first interface"
    qos:
      - qos1
      - qos2
  eth2:
    name: WAN
    description: "My second interface"
    qos:
      - qos1
      - qos3
    password: 1234
qos:
  qos1:
    name: "100M"
    description: "My first QoS"
    bandwidth: 100mbps
    netem: delay 100ms 10ms distribution experimental
  qos2:
    name: "10M"
    description: "My second QoS"
    bandwidth: 10mbps
    netem: delay 200ms 10ms
  qos3:
    name: "1M"
    description: "My third QoS"
    bandwidth: 1mbps
    netem: delay 500ms 30ms
"""
        r = Router.load(yaml.load(doc))
        self.assertEqual(r.incoming, ["eth0"])
        self.assertEqual(r.clients, {})
        self.assertEqual(r.interfaces["eth1"],
                         Interface("LAN", "My first interface",
                                    qos={'qos1': QoS("100M", "My first QoS",
                                             {"bandwidth": "100mbps",
                                              "netem": "delay 100ms 10ms distribution experimental"}),
                                         'qos2': QoS("10M", "My second QoS",
                                             {"bandwidth": "10mbps",
                                              "netem": "delay 200ms 10ms"})}))
        self.assertEqual(r.interfaces["eth2"],
                         Interface("WAN", "My second interface",
                                   qos={'qos1': QoS("100M", "My first QoS",
                                            {"bandwidth": "100mbps",
                                             "netem": "delay 100ms 10ms distribution experimental"}),
                                        'qos3': QoS("1M", "My third QoS",
                                            {"bandwidth": "1mbps",
                                             "netem": "delay 500ms 30ms"})}))
        self.assertEqual(len(r.interfaces), 2)
        self.assertEqual(r.interfaces["eth2"].check_password("1234"), True)
Example #12
0
 def test_router(self):
     """Create a complete router"""
     q1 = QoS("100M", "My first QoS")
     q2 = QoS("10M", "My second QoS")
     i1 = Interface("LAN", "My second interface", {'qos1': q1, 'qos2': q2})
     i2 = Interface("WAN", "My third interface", {'qos1': q1})
     r = Router("eth0", interfaces={'eth1': i1, 'eth2': i2})
     self.assertEqual(r.incoming, ["eth0"])
     self.assertEqual(r.clients, {})
     self.assertEqual(r.interfaces, {'eth1': i1, 'eth2': i2})
Example #13
0
 def test_unbind_client(self):
     """Unbind a client"""""
     q1 = QoS("100M", "My first QoS")
     i1 = Interface("WAN", "My third interface", {'qos1': q1})
     r = Router("eth0", interfaces={'eth2': i1})
     r.bind("192.168.15.2", "eth2", "qos1")
     r.bind("192.168.15.3", "eth2", "qos1")
     r.unbind("192.168.15.2")
     with self.assertRaises(KeyError):
         r.clients["192.168.15.2"]
     self.assertEqual(len(r.clients), 1)
     r.unbind("192.168.15.2")
     self.assertEqual(len(r.clients), 1)
Example #14
0
    def test_load_unknown_qos(self):
        """Load router from YAML with unknown QoS"""
        doc = """
clients: eth0
interfaces:
  eth1:
    name: LAN
    description: "My first interface"
    qos:
      - qos3
"""
        with self.assertRaises(KeyError):
            r = Router.load(yaml.load(doc))
Example #15
0
    def test_load_almost_minimal(self):
        """Load router with almost minimal information"""
        doc = """
clients: eth0
interfaces:
  eth1:
    name: LAN
    description: "My first interface"
"""
        r = Router.load(yaml.load(doc))
        self.assertEqual(r.interfaces, {'eth1': Interface("LAN", "My first interface")})
        self.assertEqual(r.incoming, ["eth0"])
        self.assertEqual(r.clients, {})
Example #16
0
    def test_several_incoming(self):
        """Load router with several incoming interfaces"""
        doc = """
clients:
  - eth0
  - eth2
interfaces:
  eth1:
    name: LAN
    description: "My first interface"
"""
        r = Router.load(yaml.load(doc))
        self.assertEqual(r.incoming, ["eth0", "eth2"])
Example #17
0
 def test_bind_with_password(self):
     """Bind a password protected interface"""
     q1 = QoS("100M", "My first QoS")
     q2 = QoS("10M", "My second QoS")
     i1 = Interface("LAN", "My second interface", {'qos1': q1, 'qos2': q2},
                    password="******")
     i2 = Interface("WAN", "My third interface", {'qos1': q1})
     r = Router("eth0", interfaces={'eth1': i1, 'eth2': i2})
     r.bind("192.168.15.2", "eth1", "qos2", password="******")
     r.bind("192.168.15.3", "eth2", "qos1")
     r.bind("192.168.15.4", "eth1", "qos2", password=1234)
     r.bind("192.168.15.5", "eth2", "qos1", password=4574)
     self.assertEqual(r.clients["192.168.15.2"], ('eth1', 'qos2'))
     self.assertEqual(r.clients["192.168.15.3"], ('eth2', 'qos1'))
     self.assertEqual(r.clients["192.168.15.4"], ('eth1', 'qos2'))
     self.assertEqual(r.clients["192.168.15.5"], ('eth2', 'qos1'))
Example #18
0
 def test_bind_inexistant(self):
     """Client binding to inexistant interface or QoS"""
     q1 = QoS("100M", "My first QoS")
     q2 = QoS("10M", "My second QoS")
     i1 = Interface("LAN", "My second interface", {'qos1': q1, 'qos2': q2})
     i2 = Interface("WAN", "My third interface", {'qos1': q1})
     r = Router("eth0", interfaces={'eth1': i1, 'eth2': i2})
     with self.assertRaises(KeyError):
         r.bind("192.168.15.2", "eth3", "qos2")
     with self.assertRaises(KeyError):
         r.bind("192.168.15.2", "eth2", "qos2")
Example #19
0
 def test_double_bind_client(self):
     """Try to bind a client twice"""
     q1 = QoS("100M", "My first QoS")
     i1 = Interface("LAN", "My third interface", {'qos1': q1})
     r = Router("eth0", interfaces={'eth2': i1})
     r.bind("192.168.15.2", "eth2", "qos1")
     r.bind("192.168.15.3", "eth2", "qos1")
     with self.assertRaises(ValueError):
         r.bind("192.168.15.3", "eth2", "qos1")
     self.assertEqual(r.clients["192.168.15.2"], ('eth2', 'qos1'))
     self.assertEqual(r.clients["192.168.15.3"], ('eth2', 'qos1'))
Example #20
0
 def test_bind_client(self):
     """Client binding"""
     q1 = QoS("100M", "My first QoS")
     q2 = QoS("10M", "My second QoS")
     i1 = Interface("LAN", "My second interface", {'qos1': q1, 'qos2': q2})
     i2 = Interface("WAN", "My third interface", {'qos1': q1})
     r = Router("eth0", interfaces={'eth1': i1, 'eth2': i2})
     r.bind("192.168.15.2", "eth1", "qos2")
     r.bind("192.168.15.3", "eth2", "qos1")
     r.bind("192.168.15.4", "eth1", "qos2")
     self.assertEqual(r.clients["192.168.15.2"], ('eth1', 'qos2'))
     self.assertEqual(r.clients["192.168.15.3"], ('eth2', 'qos1'))
     self.assertEqual(r.clients["192.168.15.4"], ('eth1', 'qos2'))
Example #21
0
 def test_bind_incorrect_password(self):
     """Bind with an incorrect password"""
     q1 = QoS("100M", "My first QoS")
     q2 = QoS("10M", "My second QoS")
     i1 = Interface("LAN", "My second interface", {'qos1': q1, 'qos2': q2},
                    password="******")
     r = Router("eth0", interfaces={'eth1': i1})
     with self.assertRaises(AssertionError):
         r.bind("192.168.15.2", "eth1", "qos2")
     with self.assertRaises(AssertionError):
         r.bind("192.168.15.2", "eth1", "qos2", "4512")
     with self.assertRaises(KeyError):
         r.clients["192.168.15.2"]
Example #22
0
    def setUp(self):
        r = Router.load(
            yaml.load("""
clients: eth0
interfaces:
  eth1:
    name: LAN
    description: "My first interface"
    qos:
      - qos1
      - qos2
  eth2:
    name: WAN
    description: "My second interface"
    qos:
      - qos1
      - qos3
qos:
  qos1:
    name: 100M
    description: "My first QoS"
    bandwidth: 100mbps
    netem: delay 100ms 10ms distribution experimental
  qos2:
    name: 10M
    description: "My second QoS"
    bandwidth: 10mbps
    netem: delay 200ms 10ms
  qos3:
    name: 1M
    description: "My third QoS"
    bandwidth: 1mbps
    netem: delay 500ms 30ms
"""))
        # Start the service in a separate process
        self.service = Service({}, r)
        time.sleep(0.2)  # Safety
Example #23
0
    def setUp(self):
        r = Router.load(yaml.load("""
clients: eth0
interfaces:
  eth1:
    name: LAN
    description: "My first interface"
    qos:
      - qos1
      - qos2
  eth2:
    name: WAN
    description: "My second interface"
    qos:
      - qos1
      - qos3
qos:
  qos1:
    name: 100M
    description: "My first QoS"
    bandwidth: 100mbps
    netem: delay 100ms 10ms distribution experimental
  qos2:
    name: 10M
    description: "My second QoS"
    bandwidth: 10mbps
    netem: delay 200ms 10ms
  qos3:
    name: 1M
    description: "My third QoS"
    bandwidth: 1mbps
    netem: delay 500ms 30ms
"""))
        # Start the service in a separate process
        self.service = Service({}, r)
        time.sleep(0.2)         # Safety
Example #24
0
    def setUp(self):
        self.binder = self.BINDER()
        doc = """
clients: eth0
interfaces:
  eth1:
    name: LAN
    description: "My first interface"
    qos:
      - qos1
      - qos2
  eth2:
    name: WAN
    description: "My second interface"
    qos:
      - qos1
      - qos3
      - qos4
qos:
  qos1:
    name: "100M"
    description: "My first QoS"
    bandwidth:
        down: 100mbps buffer 10Mbit latency 1s
        up: 50mbps buffer 10Mbit latency 1s
    netem: delay 100ms 10ms distribution experimental
  qos2:
    name: "10M"
    description: "My second QoS"
    bandwidth: 10mbps buffer 10Mbit latency 1s
    netem: delay 200ms 10ms
  qos3:
    name: "1M"
    description: "My third QoS"
    netem:
      down: delay 500ms 30ms
      up: delay 10ms 2ms loss 0.01%
  qos4:
    name: "unlimited"
    description: "My fourth QoS"
"""
        self.router = Router.load(yaml.load(doc))
        self.router.register(self.binder)
        # Provide fake binaries for `ip`, `iptables`, `tc`
        self.temp = tempfile.mkdtemp()
        biny = os.path.join(self.temp, "bin")
        os.mkdir(biny)
        self.oldpath = os.environ['PATH']
        os.environ['PATH'] = "%s:%s" % (biny, os.environ['PATH'])
        f = file(os.path.join(biny, "fake"), "w")
        f.write("""#!/bin/sh

echo $(basename $0) "$@" >> "%s"
case "$(basename $0) $@" in
   "iptables -t mangle -v -S kitero-ACCOUNTING")
  cat <<EOF
-N kitero-ACCOUNTING
-A kitero-ACCOUNTING -o eth2 -m connmark --mark 0x40000000/0xffe00000 -m comment --comment "up-eth2-172.29.7.14" -c 39219 2079628
-A kitero-ACCOUNTING -o eth0 -m connmark --mark 0x40000000/0xffe00000 -m comment --comment "down-eth2-172.29.7.14" -c 72867 108647983
-A kitero-ACCOUNTING -o eth2 -m connmark --mark 0x41000000/0xffe00000 -m comment --comment "up-eth2-172.29.7.15" -c 247 20796
-A kitero-ACCOUNTING -o eth0 -m connmark --mark 0x41000000/0xffe00000 -m comment --comment "down-eth2-172.29.7.15" -c 867 2015775
-A kitero-ACCOUNTING -o eth1 -m connmark --mark 0x20000000/0xffe00000 -m comment --comment "up-eth1-172.29.7.19" -c 8888 99999
-A kitero-ACCOUNTING -o eth0 -m connmark --mark 0x20000000/0xffe00000 -m comment --comment "down-eth1-172.29.7.19" -c 8888 11111
EOF
  ;;
   "ip6tables -t mangle -v -S kitero-ACCOUNTING")
  cat <<EOF
-N kitero-ACCOUNTING
-A kitero-ACCOUNTING -o eth2 -m connmark --mark 0x40000000/0xffe00000 -m comment --comment "up-eth2-2001:db8::1" -c 3219 209628
-A kitero-ACCOUNTING -o eth0 -m connmark --mark 0x40000000/0xffe00000 -m comment --comment "down-eth2-2001:db8::1" -c 7287 18647983
-A kitero-ACCOUNTING -o eth1 -m connmark --mark 0x20000000/0xffe00000 -m comment --comment "up-eth1-2001:db8::2" -c 8885 97999
-A kitero-ACCOUNTING -o eth0 -m connmark --mark 0x20000000/0xffe00000 -m comment --comment "down-eth1-2001:db8::2" -c 8885 12111
EOF
  ;;
esac
exit 0
""" % os.path.join(self.temp, "output.txt"))
        f.close()
        os.chmod(os.path.join(biny, "fake"),
                 stat.S_IXUSR | stat.S_IXGRP | stat.S_IXOTH |
                 stat.S_IRUSR | stat.S_IRGRP | stat.S_IROTH)
        for ex in ['iptables', 'ip6tables', 'tc', 'ip']:
            os.symlink("fake", os.path.join(biny, ex))
Example #25
0
    def setUp(self):
        self.binder = self.BINDER()
        doc = """
clients: eth0
interfaces:
  eth1:
    name: LAN
    description: "My first interface"
    qos:
      - qos1
      - qos2
  eth2:
    name: WAN
    description: "My second interface"
    qos:
      - qos1
      - qos3
      - qos4
qos:
  qos1:
    name: "100M"
    description: "My first QoS"
    bandwidth:
        down: 100mbps buffer 10Mbit latency 1s
        up: 50mbps buffer 10Mbit latency 1s
    netem: delay 100ms 10ms distribution experimental
  qos2:
    name: "10M"
    description: "My second QoS"
    bandwidth: 10mbps buffer 10Mbit latency 1s
    netem: delay 200ms 10ms
  qos3:
    name: "1M"
    description: "My third QoS"
    netem:
      down: delay 500ms 30ms
      up: delay 10ms 2ms loss 0.01%
  qos4:
    name: "unlimited"
    description: "My fourth QoS"
"""
        self.router = Router.load(yaml.load(doc))
        self.router.register(self.binder)
        # Provide fake binaries for `ip`, `iptables`, `tc`
        self.temp = tempfile.mkdtemp()
        biny = os.path.join(self.temp, "bin")
        os.mkdir(biny)
        self.oldpath = os.environ['PATH']
        os.environ['PATH'] = "%s:%s" % (biny, os.environ['PATH'])
        f = file(os.path.join(biny, "fake"), "w")
        f.write("""#!/bin/sh

echo $(basename $0) "$@" >> "%s"
case "$(basename $0) $@" in
   "iptables -t mangle -v -S kitero-ACCOUNTING")
  cat <<EOF
-N kitero-ACCOUNTING
-A kitero-ACCOUNTING -o eth2 -m connmark --mark 0x40000000/0xffe00000 -m comment --comment "up-eth2-172.29.7.14" -c 39219 2079628
-A kitero-ACCOUNTING -o eth0 -m connmark --mark 0x40000000/0xffe00000 -m comment --comment "down-eth2-172.29.7.14" -c 72867 108647983
-A kitero-ACCOUNTING -o eth2 -m connmark --mark 0x41000000/0xffe00000 -m comment --comment "up-eth2-172.29.7.15" -c 247 20796
-A kitero-ACCOUNTING -o eth0 -m connmark --mark 0x41000000/0xffe00000 -m comment --comment "down-eth2-172.29.7.15" -c 867 2015775
-A kitero-ACCOUNTING -o eth1 -m connmark --mark 0x20000000/0xffe00000 -m comment --comment "up-eth1-172.29.7.19" -c 8888 99999
-A kitero-ACCOUNTING -o eth0 -m connmark --mark 0x20000000/0xffe00000 -m comment --comment "down-eth1-172.29.7.19" -c 8888 11111
EOF
  ;;
   "ip6tables -t mangle -v -S kitero-ACCOUNTING")
  cat <<EOF
-N kitero-ACCOUNTING
-A kitero-ACCOUNTING -o eth2 -m connmark --mark 0x40000000/0xffe00000 -m comment --comment "up-eth2-2001:db8::1" -c 3219 209628
-A kitero-ACCOUNTING -o eth0 -m connmark --mark 0x40000000/0xffe00000 -m comment --comment "down-eth2-2001:db8::1" -c 7287 18647983
-A kitero-ACCOUNTING -o eth1 -m connmark --mark 0x20000000/0xffe00000 -m comment --comment "up-eth1-2001:db8::2" -c 8885 97999
-A kitero-ACCOUNTING -o eth0 -m connmark --mark 0x20000000/0xffe00000 -m comment --comment "down-eth1-2001:db8::2" -c 8885 12111
EOF
  ;;
esac
exit 0
""" % os.path.join(self.temp, "output.txt"))
        f.close()
        os.chmod(
            os.path.join(biny, "fake"), stat.S_IXUSR | stat.S_IXGRP
            | stat.S_IXOTH | stat.S_IRUSR | stat.S_IRGRP | stat.S_IROTH)
        for ex in ['iptables', 'ip6tables', 'tc', 'ip']:
            os.symlink("fake", os.path.join(biny, ex))
Example #26
0
 def test_bind_once(self):
     """The binder should be bound to only one router"""
     self.binder.notify("unknown", self.router)
     self.binder.notify("unknwon", self.router)
     with self.assertRaises(ValueError):
         self.binder.notify("unknwon", Router("eth0"))
Example #27
0
 def test_empty_router(self):
     """Create an empty router"""
     r = Router("eth0")
     self.assertEqual(r.incoming, ["eth0"])
     self.assertEqual(r.interfaces, {})
     self.assertEqual(r.clients, {})
Example #28
0
    def run(cls, args=sys.argv[1:], binder=None):
        """Start the helper service.

        This method should be used to instantiate
        :class:`Service`. The configuration file must be provided as
        an argument.

        :param args: list of command line arguments
        :type args: list of strings
        :param binder: binder to register to the router
        """
        from optparse import OptionParser
        usage = "usage: %prog [options] config.yaml"
        parser = OptionParser(usage=usage)
        parser.add_option("-l", "--log",
                          type="string", dest="log",
                          help="log to file",
                          metavar="FILE")
        parser.add_option("-s", "--syslog",
                          action="store_true", dest="syslog",
                          help="log to syslog")
        parser.add_option("-d", "--debug",
                          action="count", dest="debug",
                          help="enable debugging")
        (options, args) = parser.parse_args(args)
        if len(args) != 1:
            parser.error("incorrect number of arguments")

        # Logger configuration
        l = logging.root
        if options.debug == 1:
            l.setLevel(logging.INFO)
        if options.debug > 1:
            l.setLevel(logging.DEBUG)
        if options.log:
            fh = logging.FileHandler(options.log)
            fh.setFormatter(
                logging.Formatter('%(asctime)s %(name)s[%(process)d] '
                                  '%(levelname)s: %(message)s'))
            l.addHandler(fh)
        if options.syslog:
            sh = logging.handlers.SysLogHandler(address='/dev/log',
                                                facility="daemon")
            sh.setFormatter(
                logging.Formatter('kitero[%(process)d]: '
                                  '%(levelname)s %(message)s'))
            l.addHandler(sh)
        if not options.syslog and not options.log:
            # Log to stderr
            eh = logging.StreamHandler()
            eh.setFormatter(
                logging.Formatter('%(asctime)s %(name)s[%(process)d] '
                                  '%(levelname)s: %(message)s'))
            l.addHandler(eh)

        # Reading configuration file
        logger.info("read configuration file %r" % args[0])
        try:
            config = yaml.safe_load(file(args[0]))
            config = kitero.config.merge(config)
            # Create the router
            router = Router.load(config['router'])
            # Add the regular binder to it
            if binder is not None:
                router.register(binder)
            # Start service
            s = cls(config, router)
            s.wait()
        except Exception as e:
            logger.exception("unhandled error received")
            sys.exit(1)
        sys.exit(0)
Example #29
0
 def test_multiple_incoming(self):
     """Create an empty router with several incoming interfaces"""
     r = Router(["eth0", "eth2"])
     self.assertEqual(r.incoming, ["eth0", "eth2"])
     self.assertEqual(r.interfaces, {})
     self.assertEqual(r.clients, {})
Example #30
0
 def test_router_with_shared_interface(self):
     """Try to create router with duplicate interfaces"""
     i1 = Interface("LAN", "My second interface")
     i2 = Interface("WAN", "My third interface")
     with self.assertRaises(ValueError):
         r = Router("eth0", interfaces={'eth0': i1, 'eth1': i2})
Example #31
0
 def realSetup(self):
     self.router = Router.load(self.config)
     # Start the service in a separate process
     self.service = Service(dict(helper=dict(save=os.path.join(self.temp, "save.pickle"))),
                            self.router)
     time.sleep(0.2)         # Safety
Example #32
0
class TestRouterObserver(unittest.TestCase):
    def setUp(self):
        q1 = QoS("100M", "My first QoS")
        q2 = QoS("10M", "My second QoS")
        i1 = Interface("LAN", "My second interface", {'qos1': q1, 'qos2': q2})
        i2 = Interface("WAN", "My third interface", {'qos1': q1})
        self.router = Router("eth0", interfaces={'eth1': i1, 'eth2': i2})

    def test_register_observer(self):
        """Register an observer and receive events"""
        last = {}
        class Observer(object):
            zope.interface.implements(IBinder)
            def notify(self, event, source, **kwargs):
                last['event'] = event
                last['source'] = source
                last['args'] = kwargs
        self.router.register(Observer())
        self.router.bind("192.168.15.2", "eth2", "qos1")
        self.assertEqual(last['event'], 'bind')
        self.assertEqual(last['source'], self.router)
        self.assertEqual(last['args']['client'], '192.168.15.2')
        self.assertEqual(last['args']['interface'], 'eth2')
        self.assertEqual(last['args']['qos'], 'qos1')
        self.router.bind("192.168.15.3", "eth2", "qos1")
        self.assertEqual(last['event'], 'bind')
        self.assertEqual(last['source'], self.router)
        self.assertEqual(last['args']['client'], '192.168.15.3')
        self.assertEqual(last['args']['interface'], 'eth2')
        self.assertEqual(last['args']['qos'], 'qos1')
        self.router.unbind("192.168.15.3")
        self.assertEqual(last['event'], 'unbind')
        self.assertEqual(last['source'], self.router)
        self.assertEqual(last['args']['client'], '192.168.15.3')

    def test_register_not_observer(self):
        """Register something which is not an observer"""
        last = {}
        class Observer(object):
            def notify(self, event, source, **kwargs):
                """Will not be called"""
        with self.assertRaises(ValueError):
            self.router.register(Observer())

    def test_register_several_observers(self):
        """Register several observers"""
        events = {}
        class Observer(object):
            zope.interface.implements(IBinder)
            def notify(self, event, source, **kwargs):
                events[self] = event
        obs1 = Observer()
        obs2 = Observer()
        obs3 = Observer()
        self.router.register(obs1)
        self.router.register(obs2)
        self.router.register(obs3)
        self.router.bind("192.168.15.2", "eth2", "qos1")
        self.assertEqual(events, {obs1: 'bind',
                                  obs2: 'bind',
                                  obs3: 'bind'})

    def test_observer_pickling(self):
        """Check if observers are notified on unpickling"""
        temp = tempfile.mkdtemp()
        try:
            testfile = os.path.join(temp, "testfile.txt")
            self.router.register(PickableObserver(testfile))
            self.router.bind("192.168.15.2", "eth2", "qos1")
            self.assertEqual(file(testfile).read(), "bind\n")
            r = pickle.loads(pickle.dumps(self.router))
            self.assertEqual(self.router, r)
            self.assertEqual(self.router.clients, r.clients)
            self.assertEqual(file(testfile).read(), "bind\nbind\n")
        finally:
            shutil.rmtree(temp)

    def test_stats(self):
        """Register an observer that also implements IStatsProvider"""
        class Observer(object):
            zope.interface.implements(IBinder, IStatsProvider)
            def notify(self, event, source, **kwargs):
                """Do nothing"""
            def stats(self):
                return {'eth1': {'up': 47, 'down': 255},
                        'eth2': {'clients': 2, 'details': {'172.14.15.16': {'up': 1, 'down': 2}}}}
        self.assertEqual(self.router.stats,
                         {'eth1': {'clients': 0, 'details': {}},
                          'eth2': {'clients': 0, 'details': {}}})
        self.router.register(Observer())
        self.assertEqual(self.router.stats,
                         {'eth1': {'clients': 0, 'up': 47, 'down': 255, 'details': {}},
                          'eth2': {'clients': 0, 'details': {}}})
Example #33
0
 def setUp(self):
     q1 = QoS("100M", "My first QoS")
     q2 = QoS("10M", "My second QoS")
     i1 = Interface("LAN", "My second interface", {'qos1': q1, 'qos2': q2})
     i2 = Interface("WAN", "My third interface", {'qos1': q1})
     self.router = Router("eth0", interfaces={'eth1': i1, 'eth2': i2})