Example #1
0
    def __init__(self, db_peer=None):
        if type(db_peer) not in [str, bytes] and not self.db_peer:
            raise TypeError("Database address should be in string format")

        protocol = db_peer[:db_peer.find('//') - 1]

        if protocol == 'unix':
            self.sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
            self.sock.connect(db_peer[db_peer.find('//') + 2:])

        elif protocol == 'tcp':
            self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
            self.sock.connect(
                tuple(db_peer[db_peer.find('//') + 2:].split(":")))

        else:
            raise OVSExceptions.OVSUnsupportedProtocol

        self.monitor_id = None
        self.ovs_state = OpenvSwitchState()
    def __init__(self, db_peer=None):
        if type(db_peer) not in [str, bytes] and not self.db_peer:
            raise TypeError("Database address should be in string format")

        protocol = db_peer[: db_peer.find("//") - 1]

        if protocol == "unix":
            self.sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
            self.sock.connect(db_peer[db_peer.find("//") + 2 :])

        elif protocol == "tcp":
            self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
            self.sock.connect(tuple(db_peer[db_peer.find("//") + 2 :].split(":")))

        else:
            raise OVSExceptions.OVSUnsupportedProtocol

        self.monitor_id = None
        self.ovs_state = OpenvSwitchState()
Example #3
0
class OpenvSwitchClient(object):

    BUFF_SIZE = 32768
    cur_id = 0

    def __init__(self, db_peer=None):
        if type(db_peer) not in [str, bytes] and not self.db_peer:
            raise TypeError("Database address should be in string format")

        protocol = db_peer[:db_peer.find('//') - 1]

        if protocol == 'unix':
            self.sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
            self.sock.connect(db_peer[db_peer.find('//') + 2:])

        elif protocol == 'tcp':
            self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
            self.sock.connect(
                tuple(db_peer[db_peer.find('//') + 2:].split(":")))

        else:
            raise OVSExceptions.OVSUnsupportedProtocol

        self.monitor_id = None
        self.ovs_state = OpenvSwitchState()

    def commit(self, transaction):
        if not isinstance(transaction, Transaction):
            raise OVSExceptions.OVSValueError("Unexpected Transaction Value")
        self.sock.send(bytes(json.dumps(transaction)), 'utf-8')
        responses = self.get_responses(self.sock.recv(self.BUFF_SIZE))
        for response in responses:
            res = json.loads(response)
            transaction.handleResult(res)
            self.update_notification(res)
        self.cur_id += 1

    def get_responses(self, response_str):
        objects = []
        response_str = response_str.decode('utf-8')
        while response_str.find('}{') != -1:
            obj = response_str[:response_str.find('}{') + 1]
            objects.append(obj)
            response_str = response_str[len(obj):]
        objects.append(response_str)
        return objects

    def getState(self, monitor_requests):
        # Monitor params should be:
        #  - Tables
        updates = []
        response = None
        params = ["Open_vSwitch", None, dict()]
        for request in monitor_requests:
            params[2][request.name] = request

        payload = {'method': 'monitor', 'id': self.cur_id, 'params': params}
        self.sock.send(bytes(json.dumps(payload), 'utf-8'))

        self.monitor_id = self.cur_id
        responses = self.get_responses(self.sock.recv(self.BUFF_SIZE))
        for response in responses:
            res = json.loads(response)
            update = self.update_notification(res)
            if update:
                updates.append(update)
        for response in updates:
            self.ovs_state.update(response)
        self.cur_id += 1
        return self.ovs_state

    def update_notification(self, response):
        if 'method' in response and response['method'] == 'update':
            self.ovs_state.update(response)
            return None
        return response

    def addBridge(self, bridge_name):
        switch = self.ovs_state.switch
        if bridge_name in \
                [br.name for br in list(self.ovs_state.bridges.values()) if br.name == bridge_name]:
            raise OVSExceptions.OVSBridgeExists(bridge_name)

        transaction = Transaction(self.cur_id)

        # Generate Wait operations
        for instance in list(self.ovs_state.ports.values()) + list(
                self.ovs_state.bridges.values()):
            transaction.addOperation(WaitOperation(instance))

        # Build sub-components of a bridge
        intern_if = OVSInterface(bridge_name)
        intern_if.type = 'internal'
        intern_port = OVSPort(bridge_name, [intern_if])
        bridge = OVSBridge(bridge_name, [intern_port])

        # Generate Insert Operations for built components
        transaction.addOperation(InsertOperation(intern_if))
        transaction.addOperation(InsertOperation(intern_port))
        transaction.addOperation(InsertOperation(bridge))

        switch.addBridge(bridge)
        transaction.addOperation(UpdateOperation(switch, ['bridges']))
        transaction.addOperation(MutateOperation(switch, 'next_cfg', '+='))
        self.sock.send(bytes(json.dumps(transaction), 'utf-8'))
        del switch.bridges[bridge.uuid]
        handled = False
        while not handled:
            responses = self.get_responses(self.sock.recv(self.BUFF_SIZE))
            for response in responses:
                res = json.loads(response)
                handled = transaction.handleResult(res)
                self.update_notification(res)
        self.cur_id += 1

    def removeBridge(self, bridge_name):
        switch = self.ovs_state.switch
        bridge = None
        if bridge_name in \
                [br.name for br in list(switch.bridges.values())]:
            bridge = [
                br for br in list(switch.bridges.values())
                if br.name == bridge_name
            ][0]
        else:
            raise OVSExceptions.OVSNoSuchBridge(bridge_name)

        transaction = Transaction(self.cur_id)
        transaction.addOperation(WaitOperation(switch))
        self.ovs_state.removeBridge(bridge.uuid)
        transaction.addOperation(UpdateOperation(switch, ['bridges']))
        transaction.addOperation(MutateOperation(switch, 'next_cfg', '+='))
        self.sock.send(bytes(json.dumps(transaction), 'utf-8'))
        responses = self.get_responses(self.sock.recv(self.BUFF_SIZE))

        for response in responses:
            res = json.loads(response)
            transaction.handleResult(res)
        self.cur_id += 1

    def bridgeExists(self, br_name):
        if br_name in \
                [br.name for br in list(self.ovs_state.bridges.values())]:
            return True
        return False

    def portExists(self, port_name):
        if port_name in \
                [port.name for port in list(self.ovs_state.ports.values())]:
            return True
        return False

    def interfaceExists(self, if_name):
        if if_name in \
                [iface.name for iface in list(self.ovs_state.interfaces.values())]:
            return True
        return False

    def addPort(self, bridge_name, port_name):
        if bridge_name not in \
                [br.name for br in list(self.ovs_state.bridges.values())]:
            raise OVSExceptions.OVSNoSuchBridge(bridge_name)
        if port_name in \
                [port.name for port in list(self.ovs_state.ports.values())]:
            raise OVSExceptions.OVSPortExists(port_name)

        transaction = Transaction(self.cur_id)
        for instance in list(self.ovs_state.bridges.values()) + list(
                self.ovs_state.ports.values()):
            transaction.addOperation(WaitOperation(instance))
        switch = self.ovs_state.switch
        iface = OVSInterface(port_name)
        port = OVSPort(port_name, [iface])
        transaction.addOperation(InsertOperation(iface))
        transaction.addOperation(InsertOperation(port))
        bridge = None
        for br in list(self.ovs_state.bridges.values()):
            if br.name == bridge_name:
                bridge = br
                break
        bridge.ports[port.uuid] = port
        transaction.addOperation(UpdateOperation(bridge, 'ports'))
        transaction.addOperation(MutateOperation(switch, 'next_cfg', '+='))
        self.sock.send(bytes(json.dumps(transaction), 'utf-8'))
        del bridge.ports[port.uuid]
        responses = self.get_responses(self.sock.recv(self.BUFF_SIZE))
        for response in responses:
            res = json.loads(response)
            transaction.handleResult(res)
            self.update_notification(res)
        self.cur_id += 1
        return True

    def removePort(self, port_name):
        if port_name not in \
                [port.name for port in list(self.ovs_state.ports.values())]:
            raise OVSExceptions.OVSNoSuchPort(port_name)

        switch = self.ovs_state.switch
        transaction = Transaction(self.cur_id)
        for instance in list(self.ovs_state.bridges.values()) + list(
                self.ovs_state.ports.values()):
            transaction.addOperation(WaitOperation(instance))

        port = None
        for p in list(self.ovs_state.ports.values()):
            if p.name == port_name:
                port = p
                break
        bridge = self.ovs_state.removePort(port.uuid)
        transaction.addOperation(UpdateOperation(bridge, 'ports'))
        transaction.addOperation(MutateOperation(switch, 'next_cfg', '+='))
        self.sock.send(bytes(json.dumps(transaction), 'utf-8'))

        responses = self.get_responses(self.sock.recv(self.BUFF_SIZE))
        for response in responses:
            res = json.loads(response)
            transaction.handleResult(res)
        self.cur_id += 1
        return True

    def getBridge(self, bridge_name):
        for bridge in list(self.ovs_state.bridges.values()):
            if bridge.name == bridge_name:
                return bridge
        raise IndexError("No such bridge")

    def getPort(self, port_name):
        for port in list(self.ovs_state.ports.values()):
            if port.name == port_name:
                return port
        raise IndexError("No such port")

    def getInterface(self, interface_name):
        for interface in list(self.ovs_state.interfaces.values()):
            if interface.name == interface_name:
                return interface
        raise IndexError("No such port")

    def setBridgeProperty(self, bridge_name, option, value):
        bridge = self.getBridge(bridge_name)
        if hasattr(bridge, option):
            setattr(bridge, option, value)
        t = Transaction(self.cur_id)
        t.addOperation(WaitOperation(bridge))
        t.addOperation(UpdateOperation(bridge))
        t.addOperation(MutateOperation(self.ovs_state.switch, 'next_cfg',
                                       '+='))
        self.sock.send(bytes(json.dumps(t), 'utf-8'))

        responses = self.get_responses(self.sock.recv(self.BUFF_SIZE))
        for response in responses:
            res = json.loads(response)
            t.handleResult(res)
            self.update_notification(res)
        self.cur_id += 1

    def setPortProperty(self, port_name, option, value):
        port = self.getPort(port_name)
        if hasattr(port, option):
            setattr(port, option, value)
        t = Transaction(self.cur_id)
        t.addOperation(WaitOperation(port))
        t.addOperation(UpdateOperation(port))
        t.addOperation(MutateOperation(self.ovs_state.switch, 'next_cfg',
                                       '+='))
        self.sock.send(bytes(json.dumps(t), 'utf-8'))

        responses = self.get_responses(self.sock.recv(self.BUFF_SIZE))
        for response in responses:
            res = json.loads(response)
            t.handleResult(res)
            self.update_notification(res)
        self.cur_id += 1

    def setInterfaceProperty(self, interface_name, option, value):
        interface = self.getInterface(interface_name)
        if hasattr(interface, option):
            setattr(interface, option, value)

        t = Transaction(self.cur_id)
        t.addOperation(UpdateOperation(interface))
        t.addOperation(MutateOperation(self.ovs_state.switch, 'next_cfg',
                                       '+='))
        self.sock.send(bytes(json.dumps(t), 'utf-8'))
        responses = self.get_responses(self.sock.recv(self.BUFF_SIZE))
        for response in responses:
            res = json.loads(response)
            t.handleResult(res)
            self.update_notification(res)
        interface = self.getInterface(interface_name)
        self.cur_id += 1

    def cancel_transact(self, transact_id):
        pass

    def cancel_monitor(self):
        pass
class OpenvSwitchClient(object):

    BUFF_SIZE = 32768
    cur_id = 0

    def __init__(self, db_peer=None):
        if type(db_peer) not in [str, bytes] and not self.db_peer:
            raise TypeError("Database address should be in string format")

        protocol = db_peer[: db_peer.find("//") - 1]

        if protocol == "unix":
            self.sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
            self.sock.connect(db_peer[db_peer.find("//") + 2 :])

        elif protocol == "tcp":
            self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
            self.sock.connect(tuple(db_peer[db_peer.find("//") + 2 :].split(":")))

        else:
            raise OVSExceptions.OVSUnsupportedProtocol

        self.monitor_id = None
        self.ovs_state = OpenvSwitchState()

    def commit(self, transaction):
        if not isinstance(transaction, Transaction):
            raise OVSExceptions.OVSValueError("Unexpected Transaction Value")
        self.sock.send(bytes(json.dumps(transaction)), "utf-8")
        responses = self.get_responses(self.sock.recv(self.BUFF_SIZE))
        for response in responses:
            res = json.loads(response)
            transaction.handleResult(res)
            self.update_notification(res)
        self.cur_id += 1

    def get_responses(self, response_str):
        objects = []
        response_str = response_str.decode("utf-8")
        while response_str.find("}{") != -1:
            obj = response_str[: response_str.find("}{") + 1]
            objects.append(obj)
            response_str = response_str[len(obj) :]
        objects.append(response_str)
        return objects

    def getState(self, monitor_requests):
        # Monitor params should be:
        #  - Tables
        updates = []
        response = None
        params = ["Open_vSwitch", None, dict()]
        for request in monitor_requests:
            params[2][request.name] = request

        payload = {"method": "monitor", "id": self.cur_id, "params": params}
        self.sock.send(bytes(json.dumps(payload), "utf-8"))

        self.monitor_id = self.cur_id
        responses = self.get_responses(self.sock.recv(self.BUFF_SIZE))
        for response in responses:
            res = json.loads(response)
            update = self.update_notification(res)
            if update:
                updates.append(update)
        for response in updates:
            self.ovs_state.update(response)
        self.cur_id += 1
        return self.ovs_state

    def update_notification(self, response):
        if "method" in response and response["method"] == "update":
            self.ovs_state.update(response)
            return None
        return response

    def addBridge(self, bridge_name):
        switch = self.ovs_state.switch
        if bridge_name in [br.name for br in list(self.ovs_state.bridges.values()) if br.name == bridge_name]:
            raise OVSExceptions.OVSBridgeExists(bridge_name)

        transaction = Transaction(self.cur_id)

        # Generate Wait operations
        for instance in list(self.ovs_state.ports.values()) + list(self.ovs_state.bridges.values()):
            transaction.addOperation(WaitOperation(instance))

        # Build sub-components of a bridge
        intern_if = OVSInterface(bridge_name)
        intern_if.type = "internal"
        intern_port = OVSPort(bridge_name, [intern_if])
        bridge = OVSBridge(bridge_name, [intern_port])

        # Generate Insert Operations for built components
        transaction.addOperation(InsertOperation(intern_if))
        transaction.addOperation(InsertOperation(intern_port))
        transaction.addOperation(InsertOperation(bridge))

        switch.addBridge(bridge)
        transaction.addOperation(UpdateOperation(switch, ["bridges"]))
        transaction.addOperation(MutateOperation(switch, "next_cfg", "+="))
        self.sock.send(bytes(json.dumps(transaction), "utf-8"))
        del switch.bridges[bridge.uuid]
        handled = False
        while not handled:
            responses = self.get_responses(self.sock.recv(self.BUFF_SIZE))
            for response in responses:
                res = json.loads(response)
                handled = transaction.handleResult(res)
                self.update_notification(res)
        self.cur_id += 1

    def removeBridge(self, bridge_name):
        switch = self.ovs_state.switch
        bridge = None
        if bridge_name in [br.name for br in list(switch.bridges.values())]:
            bridge = [br for br in list(switch.bridges.values()) if br.name == bridge_name][0]
        else:
            raise OVSExceptions.OVSNoSuchBridge(bridge_name)

        transaction = Transaction(self.cur_id)
        transaction.addOperation(WaitOperation(switch))
        self.ovs_state.removeBridge(bridge.uuid)
        transaction.addOperation(UpdateOperation(switch, ["bridges"]))
        transaction.addOperation(MutateOperation(switch, "next_cfg", "+="))
        self.sock.send(bytes(json.dumps(transaction), "utf-8"))
        responses = self.get_responses(self.sock.recv(self.BUFF_SIZE))

        for response in responses:
            res = json.loads(response)
            transaction.handleResult(res)
        self.cur_id += 1

    def bridgeExists(self, br_name):
        if br_name in [br.name for br in list(self.ovs_state.bridges.values())]:
            return True
        return False

    def portExists(self, port_name):
        if port_name in [port.name for port in list(self.ovs_state.ports.values())]:
            return True
        return False

    def interfaceExists(self, if_name):
        if if_name in [iface.name for iface in list(self.ovs_state.interfaces.values())]:
            return True
        return False

    def addPort(self, bridge_name, port_name):
        if bridge_name not in [br.name for br in list(self.ovs_state.bridges.values())]:
            raise OVSExceptions.OVSNoSuchBridge(bridge_name)
        if port_name in [port.name for port in list(self.ovs_state.ports.values())]:
            raise OVSExceptions.OVSPortExists(port_name)

        transaction = Transaction(self.cur_id)
        for instance in list(self.ovs_state.bridges.values()) + list(self.ovs_state.ports.values()):
            transaction.addOperation(WaitOperation(instance))
        switch = self.ovs_state.switch
        iface = OVSInterface(port_name)
        port = OVSPort(port_name, [iface])
        transaction.addOperation(InsertOperation(iface))
        transaction.addOperation(InsertOperation(port))
        bridge = None
        for br in list(self.ovs_state.bridges.values()):
            if br.name == bridge_name:
                bridge = br
                break
        bridge.ports[port.uuid] = port
        transaction.addOperation(UpdateOperation(bridge, "ports"))
        transaction.addOperation(MutateOperation(switch, "next_cfg", "+="))
        self.sock.send(bytes(json.dumps(transaction), "utf-8"))
        del bridge.ports[port.uuid]
        responses = self.get_responses(self.sock.recv(self.BUFF_SIZE))
        for response in responses:
            res = json.loads(response)
            transaction.handleResult(res)
            self.update_notification(res)
        self.cur_id += 1
        return True

    def removePort(self, port_name):
        if port_name not in [port.name for port in list(self.ovs_state.ports.values())]:
            raise OVSExceptions.OVSNoSuchPort(port_name)

        switch = self.ovs_state.switch
        transaction = Transaction(self.cur_id)
        for instance in list(self.ovs_state.bridges.values()) + list(self.ovs_state.ports.values()):
            transaction.addOperation(WaitOperation(instance))

        port = None
        for p in list(self.ovs_state.ports.values()):
            if p.name == port_name:
                port = p
                break
        bridge = self.ovs_state.removePort(port.uuid)
        transaction.addOperation(UpdateOperation(bridge, "ports"))
        transaction.addOperation(MutateOperation(switch, "next_cfg", "+="))
        self.sock.send(bytes(json.dumps(transaction), "utf-8"))

        responses = self.get_responses(self.sock.recv(self.BUFF_SIZE))
        for response in responses:
            res = json.loads(response)
            transaction.handleResult(res)
        self.cur_id += 1
        return True

    def getBridge(self, bridge_name):
        for bridge in list(self.ovs_state.bridges.values()):
            if bridge.name == bridge_name:
                return bridge
        raise IndexError("No such bridge")

    def getPort(self, port_name):
        for port in list(self.ovs_state.ports.values()):
            if port.name == port_name:
                return port
        raise IndexError("No such port")

    def getInterface(self, interface_name):
        for interface in list(self.ovs_state.interfaces.values()):
            if interface.name == interface_name:
                return interface
        raise IndexError("No such port")

    def setBridgeProperty(self, bridge_name, option, value):
        bridge = self.getBridge(bridge_name)
        if hasattr(bridge, option):
            setattr(bridge, option, value)
        t = Transaction(self.cur_id)
        t.addOperation(WaitOperation(bridge))
        t.addOperation(UpdateOperation(bridge))
        t.addOperation(MutateOperation(self.ovs_state.switch, "next_cfg", "+="))
        self.sock.send(bytes(json.dumps(t), "utf-8"))

        responses = self.get_responses(self.sock.recv(self.BUFF_SIZE))
        for response in responses:
            res = json.loads(response)
            t.handleResult(res)
            self.update_notification(res)
        self.cur_id += 1

    def setPortProperty(self, port_name, option, value):
        port = self.getPort(port_name)
        if hasattr(port, option):
            setattr(port, option, value)
        t = Transaction(self.cur_id)
        t.addOperation(WaitOperation(port))
        t.addOperation(UpdateOperation(port))
        t.addOperation(MutateOperation(self.ovs_state.switch, "next_cfg", "+="))
        self.sock.send(bytes(json.dumps(t), "utf-8"))

        responses = self.get_responses(self.sock.recv(self.BUFF_SIZE))
        for response in responses:
            res = json.loads(response)
            t.handleResult(res)
            self.update_notification(res)
        self.cur_id += 1

    def setInterfaceProperty(self, interface_name, option, value):
        interface = self.getInterface(interface_name)
        if hasattr(interface, option):
            setattr(interface, option, value)

        t = Transaction(self.cur_id)
        t.addOperation(UpdateOperation(interface))
        t.addOperation(MutateOperation(self.ovs_state.switch, "next_cfg", "+="))
        self.sock.send(bytes(json.dumps(t), "utf-8"))
        responses = self.get_responses(self.sock.recv(self.BUFF_SIZE))
        for response in responses:
            res = json.loads(response)
            t.handleResult(res)
            self.update_notification(res)
        interface = self.getInterface(interface_name)
        self.cur_id += 1

    def cancel_transact(self, transact_id):
        pass

    def cancel_monitor(self):
        pass