示例#1
0
    def __init__(self, interface, **kwargs):
        self.addr = None
        self.range_buckets = {}
        self.tunnel_bucket = {}
        self.interface = interface
        for i in range(1, 255):
            self.tunnel_bucket[i] = None
            # Only used by cygnet_internal (docker < 1.9.0)
            self.range_buckets[i] = None

        self['endpoints'] = kwargs['endpoints']
        self['containers'] = kwargs['containers']
        self['interfaces'] = kwargs['interfaces']
        self['internal_ip'] = kwargs['internal_ip']
        self['external_iface'] = kwargs['external_iface']
        # Add callbacks
        #
        # Should read database here
        # Initialize database client
        self.ovs_client = OpenvSwitchClient(
            'unix:///var/run/openvswitch/db.sock')
        # Tables we shall operate on
        self.ovs_client.getState(
            [OpenvSwitchTable(),
             BridgeTable(),
             PortTable(),
             InterfaceTable()])
示例#2
0
    def __init__(self, interface, **kwargs):
        self.addr = None
        self.range_buckets = {}
        self.tunnel_bucket = {}
        self.interface = interface
        for i in range(1, 255):
            self.tunnel_bucket[i] = None
            # Only used by cygnet_internal (docker < 1.9.0)
            self.range_buckets[i] = None

        self['endpoints'] = kwargs['endpoints']
        self['containers'] = kwargs['containers']
        self['interfaces'] = kwargs['interfaces']
        self['internal_ip'] = kwargs['internal_ip']
        self['external_iface'] = kwargs['external_iface']
        # Add callbacks
        #
        # Should read database here
        # Initialize database client
        self.ovs_client = OpenvSwitchClient('unix:///var/run/openvswitch/db.sock')
        # Tables we shall operate on
        self.ovs_client.getState([OpenvSwitchTable(),
                                  BridgeTable(),
                                  PortTable(),
                                  InterfaceTable()])
示例#3
0
class openvswitch(dict):
    '''
        Use an OVS client to query the database for current ovs network.
    '''
    def __init__(self, interface, **kwargs):
        self.addr = None
        self.range_buckets = {}
        self.tunnel_bucket = {}
        self.interface = interface
        for i in range(1, 255):
            self.tunnel_bucket[i] = None
            # Only used by cygnet_internal (docker < 1.9.0)
            self.range_buckets[i] = None

        self['endpoints'] = kwargs['endpoints']
        self['containers'] = kwargs['containers']
        self['interfaces'] = kwargs['interfaces']
        self['internal_ip'] = kwargs['internal_ip']
        self['external_iface'] = kwargs['external_iface']
        # Add callbacks
        #
        # Should read database here
        # Initialize database client
        self.ovs_client = OpenvSwitchClient('unix:///var/run/openvswitch/db.sock')
        # Tables we shall operate on
        self.ovs_client.getState([OpenvSwitchTable(),
                                  BridgeTable(),
                                  PortTable(),
                                  InterfaceTable()])

    def __getattribute__(self, key, *args):
        try:
            return dict.__getattribute__(self, key)
        except AttributeError as e:
            if key in self:
                return self[key]
            else:
                raise e

    def __setattr__(self, key, value):
        try:
            dict.__setattr__(self, key, value)
        except AttributeError as e:
            if key in self:
                self[key] = value
            else:
                raise e

    def __delattr__(self, key):
        try:
            dict.__delattr__(self, key)
        except AttributeError as e:
            if key in self:
                del self[key]
            else:
                raise e

    def __ovs_setup(self):
        if not self.ovs_client.bridgeExists('cygnet0'):
            self.ovs_client.addBridge('cygnet0')
            self.ovs_client.addPort('cygnet0', self.external_iface)
        elif not self.ovs_client.portExists(self.external_iface):
            self.ovs_client.addPort('cygnet0', self.external_iface)
        ip = IPDB()
        ifaces = ip.interfaces
        ifaces.cygnet0.begin()
        addrs= ip.interfaces[self.external_iface].ipaddr.raw
        addr = None
        for address, attrs in addrs.items():
            if __getIPv4Addr__([address]) == None:
                continue
            addr = address
        ifaces.cygnet0.add_ip(addr[0], int(addr[1]))
        ifaces.cygnet0.up()
        ifaces.cygnet0.commit()
        ifaces[self.external_iface].begin()
        ifaces[self.external_iface].down()
        ifaces[self.external_iface].commit()

        ifaces[self.external_iface].begin()
        ifaces[self.external_iface].up()
        ifaces[self.external_iface].commit()

        ip.release()

    def initalize(self):
        # check if our setup already exists
        self.__ovs_setup()
        ip = IPDB()
        try:
            # Check if public interface is up
            self.addr = __getIPv4Addr__(list(ip.interfaces.cygnet0.ipaddr))
            self.addr = self.addr[0], str(self.addr[1])
            #self.interfaces.append(('cygnet0', self.addr))
        except Exception as e:
            raise e
        finally:
            ip.release()
        self.range_buckets[int(self.addr[0].split(".")[-1])] = 1
        return self.addr

    # initContainerNetwork should support both docker < 1.9.0
    # and docker <= 1.9.0
    # - name and network configurations should only be passed
    #   by docker plugin
    # - Otherwise, we are operating on a single internal network
    #   which is only useed by docker < 1.9.0 powerstrip adapter

    def initContainerNetwork(self, network=None):
        if not network:
            try:
                network = Network(None)
                network.name = 'cygnet_internal'
                network.address = self['internal_ip']
                if not self.ovs_client.bridgeExists(network.name):
                    self.ovs_client.addBridge(network.name)
                    self.ovs_client.setBridgeProperty(network.name,
                                                      'stp_enable',
                                                      True)
            except KeyError as e:
                print("OpenvSwitch: CYGNET_INTERNAL_IP \
                        environment variable not found")
                raise e
        else:
            network.name = "cygnet_" + network.id[:8]
            if not self.ovs_client.bridgeExists(network.name):
                self.ovs_client.addBridge(network.name)
                self.ovs_client.setBridgeProperty(network.name,
                                                  'stp_enable',
                                                  True)
        ip = IPDB()
        ifaces = ip.interfaces
        ifaces[network.name].begin()
        ifaces[network.name].add_ip(network.address, network.mask)
        ifaces[network.name].up()
        ifaces[network.name].commit()
        ip.release()
        self.interfaces.append(network)
        return network

    def destroyContainerNetwork(self, network):
        if self.ovs_client.bridgeExists(network.name):
            self.ovs_client.removeBridge(network.name)
            self.interfaces.remove(network)
            return True
        else:
            return False

    def addEndpoint(self, *endpoints):
        for endpoint in endpoints:
            keys = [key for key, value in list(self.tunnel_bucket.items()) if value is None]
            if keys:
                available = keys[0]
                self.tunnel_bucket[available] = endpoint
            else:
                raise IndexError
            for network in self.interfaces:
                iface_name = 'gre' + str(available) + "_" + network.name.split("_")[1]
                if not self.ovs_client.portExists(iface_name):
                    self.ovs_client.addPort(network.name, iface_name)
                iface = self.ovs_client.getInterface(iface_name)
                for key in iface.options[1]:
                    if isinstance(key, list):
                        if key[0] == 'remote_ip':
                            iface.options[1].remove(key)
                iface.options.append(OVSAtom(['remote_ip', endpoint]))
                iface.type = 'gre'
                self.ovs_client.setInterfaceProperty(iface_name, 'type', iface.type)
                self.ovs_client.setInterfaceProperty(iface_name,
                                                     'options',
                                                     iface.options)
    def removeEndpoint(self, *endpoints):
        for e in endpoints:
            endpoint = None
            if isinstance(e, int):
                endpoint = self.endpoints[e]
            else:
                endpoint = e
            tunnel_idx = [idx for idx, ep in list(self.tunnel_bucket.items()) if ep == endpoint]
            if tunnel_idx:
                tunnel_idx = tunnel_idx[0]
            else:
                raise ValueError
            iface_name = 'gre' + str(tunnel_idx)
            self.ovs_client.removePort(iface_name)
            # run("ovs-vsctl del-port gre"+str(tunnel_idx))
            self.tunnel_bucket[tunnel_idx] = None

    def connectContainer(self, *containers):
        for container in containers:
            if container['Interface']:
                network = container['Interface']
                run("pipework "+ network.name + " -i eth1 " + str(container.id)+ " " + container["Address"])
                return
            else:
                addr = str(container.address)
                addr_idx = int(addr.split("/")[0].split(".")[-1])
                available = (self.range_buckets[addr_idx] is None)
            if available:
                self.range_buckets[addr_idx] = container.id
                run("pipework cygnet_internal -i eth1 " + container.id + " " + addr)
            else:
                print(("Error connecting container", container.id + ": Address Already taken by container: ", self.range_buckets[addr_idx]))

    def disconnectContainer(self, *containers):
        for c in containers:
            if isinstance(c, int):
                container = self.containers[c]
            else:
                container = c
            if container['Interface']:
                container['Interface'].detachContainer(container)
            else:
                addr = str(container["Address"])
                addr_idx = int(addr.split("/")[0].split(".")[-1])
                self.range_buckets[addr_idx] = None
示例#4
0
class openvswitch(dict):
    '''
        Use an OVS client to query the database for current ovs network.
    '''
    def __init__(self, interface, **kwargs):
        self.addr = None
        self.range_buckets = {}
        self.tunnel_bucket = {}
        self.interface = interface
        for i in range(1, 255):
            self.tunnel_bucket[i] = None
            # Only used by cygnet_internal (docker < 1.9.0)
            self.range_buckets[i] = None

        self['endpoints'] = kwargs['endpoints']
        self['containers'] = kwargs['containers']
        self['interfaces'] = kwargs['interfaces']
        self['internal_ip'] = kwargs['internal_ip']
        self['external_iface'] = kwargs['external_iface']
        # Add callbacks
        #
        # Should read database here
        # Initialize database client
        self.ovs_client = OpenvSwitchClient(
            'unix:///var/run/openvswitch/db.sock')
        # Tables we shall operate on
        self.ovs_client.getState(
            [OpenvSwitchTable(),
             BridgeTable(),
             PortTable(),
             InterfaceTable()])

    def __getattribute__(self, key, *args):
        try:
            return dict.__getattribute__(self, key)
        except AttributeError as e:
            if key in self:
                return self[key]
            else:
                raise e

    def __setattr__(self, key, value):
        try:
            dict.__setattr__(self, key, value)
        except AttributeError as e:
            if key in self:
                self[key] = value
            else:
                raise e

    def __delattr__(self, key):
        try:
            dict.__delattr__(self, key)
        except AttributeError as e:
            if key in self:
                del self[key]
            else:
                raise e

    def __ovs_setup(self):
        if not self.ovs_client.bridgeExists('cygnet0'):
            self.ovs_client.addBridge('cygnet0')
            self.ovs_client.addPort('cygnet0', self.external_iface)
        elif not self.ovs_client.portExists(self.external_iface):
            self.ovs_client.addPort('cygnet0', self.external_iface)
        ip = IPDB()
        ifaces = ip.interfaces
        ifaces.cygnet0.begin()
        addrs = ip.interfaces[self.external_iface].ipaddr.raw
        addr = None
        for address, attrs in addrs.items():
            if __getIPv4Addr__([address]) == None:
                continue
            addr = address
        ifaces.cygnet0.add_ip(addr[0], int(addr[1]))
        ifaces.cygnet0.up()
        ifaces.cygnet0.commit()
        ifaces[self.external_iface].begin()
        ifaces[self.external_iface].down()
        ifaces[self.external_iface].commit()

        ifaces[self.external_iface].begin()
        ifaces[self.external_iface].up()
        ifaces[self.external_iface].commit()

        ip.release()

    def initalize(self):
        # check if our setup already exists
        self.__ovs_setup()
        ip = IPDB()
        try:
            # Check if public interface is up
            self.addr = __getIPv4Addr__(list(ip.interfaces.cygnet0.ipaddr))
            self.addr = self.addr[0], str(self.addr[1])
            #self.interfaces.append(('cygnet0', self.addr))
        except Exception as e:
            raise e
        finally:
            ip.release()
        self.range_buckets[int(self.addr[0].split(".")[-1])] = 1
        return self.addr

    # initContainerNetwork should support both docker < 1.9.0
    # and docker <= 1.9.0
    # - name and network configurations should only be passed
    #   by docker plugin
    # - Otherwise, we are operating on a single internal network
    #   which is only useed by docker < 1.9.0 powerstrip adapter

    def initContainerNetwork(self, network=None):
        if not network:
            try:
                network = Network(None)
                network.name = 'cygnet_internal'
                network.address = self['internal_ip']
                if not self.ovs_client.bridgeExists(network.name):
                    self.ovs_client.addBridge(network.name)
                    self.ovs_client.setBridgeProperty(network.name,
                                                      'stp_enable', True)
            except KeyError as e:
                print("OpenvSwitch: CYGNET_INTERNAL_IP \
                        environment variable not found")
                raise e
        else:
            network.name = "cygnet_" + network.id[:8]
            if not self.ovs_client.bridgeExists(network.name):
                self.ovs_client.addBridge(network.name)
                self.ovs_client.setBridgeProperty(network.name, 'stp_enable',
                                                  True)
        ip = IPDB()
        ifaces = ip.interfaces
        ifaces[network.name].begin()
        ifaces[network.name].add_ip(network.address, network.mask)
        ifaces[network.name].up()
        ifaces[network.name].commit()
        ip.release()
        self.interfaces.append(network)
        return network

    def destroyContainerNetwork(self, network):
        if self.ovs_client.bridgeExists(network.name):
            self.ovs_client.removeBridge(network.name)
            self.interfaces.remove(network)
            return True
        else:
            return False

    def addEndpoint(self, *endpoints):
        for endpoint in endpoints:
            keys = [
                key for key, value in list(self.tunnel_bucket.items())
                if value is None
            ]
            if keys:
                available = keys[0]
                self.tunnel_bucket[available] = endpoint
            else:
                raise IndexError
            for network in self.interfaces:
                iface_name = 'gre' + str(available) + "_" + network.name.split(
                    "_")[1]
                if not self.ovs_client.portExists(iface_name):
                    self.ovs_client.addPort(network.name, iface_name)
                iface = self.ovs_client.getInterface(iface_name)
                for key in iface.options[1]:
                    if isinstance(key, list):
                        if key[0] == 'remote_ip':
                            iface.options[1].remove(key)
                iface.options.append(OVSAtom(['remote_ip', endpoint]))
                iface.type = 'gre'
                self.ovs_client.setInterfaceProperty(iface_name, 'type',
                                                     iface.type)
                self.ovs_client.setInterfaceProperty(iface_name, 'options',
                                                     iface.options)

    def removeEndpoint(self, *endpoints):
        for e in endpoints:
            endpoint = None
            if isinstance(e, int):
                endpoint = self.endpoints[e]
            else:
                endpoint = e
            tunnel_idx = [
                idx for idx, ep in list(self.tunnel_bucket.items())
                if ep == endpoint
            ]
            if tunnel_idx:
                tunnel_idx = tunnel_idx[0]
            else:
                raise ValueError
            iface_name = 'gre' + str(tunnel_idx)
            self.ovs_client.removePort(iface_name)
            # run("ovs-vsctl del-port gre"+str(tunnel_idx))
            self.tunnel_bucket[tunnel_idx] = None

    def connectContainer(self, *containers):
        for container in containers:
            if container['Interface']:
                network = container['Interface']
                run("pipework " + network.name + " -i eth1 " +
                    str(container.id) + " " + container["Address"])
                return
            else:
                addr = str(container.address)
                addr_idx = int(addr.split("/")[0].split(".")[-1])
                available = (self.range_buckets[addr_idx] is None)
            if available:
                self.range_buckets[addr_idx] = container.id
                run("pipework cygnet_internal -i eth1 " + container.id + " " +
                    addr)
            else:
                print(("Error connecting container",
                       container.id + ": Address Already taken by container: ",
                       self.range_buckets[addr_idx]))

    def disconnectContainer(self, *containers):
        for c in containers:
            if isinstance(c, int):
                container = self.containers[c]
            else:
                container = c
            if container['Interface']:
                container['Interface'].detachContainer(container)
            else:
                addr = str(container["Address"])
                addr_idx = int(addr.split("/")[0].split(".")[-1])
                self.range_buckets[addr_idx] = None