def add_port_interfaces(puuid): # If the uuid does not appear in update info, we have no choice but to query interfaces with select # we cannot use data from other bridges; the port may be moved from a bridge which is not tracked try: method, params = ovsdb.transact('Open_vSwitch', ovsdb.select('Port', [["_uuid", "==", ovsdb.uuid(puuid)]], ["interfaces"])) for m in protocol.querywithreply(method, params, connection, self.apiroutine): yield m r = self.apiroutine.jsonrpc_result[0] if 'error' in r: raise JsonRPCErrorResultException('Error when query interfaces from port ' + repr(puuid) + ': ' + r['error']) if r['rows']: interfaces = ovsdb.getlist(r['rows'][0]['interfaces']) with closing(self.apiroutine.executeAll([self._get_interface_info(connection, protocol, buuid, iuuid, puuid) for _,iuuid in interfaces])) as g: for m in g: yield m self.apiroutine.retvalue = list(itertools.chain(r[0] for r in self.apiroutine.retvalue)) else: self.apiroutine.retvalue = [] except JsonRPCProtocolException: self.apiroutine.retvalue = [] except ConnectionResetException: self.apiroutine.retvalue = []
def _update_bridge(self, connection, protocol, bridge_uuid, vhost): try: method, params = ovsdb.transact('Open_vSwitch', ovsdb.wait('Bridge', [["_uuid", "==", ovsdb.uuid(bridge_uuid)]], ["datapath_id"], [{"datapath_id": ovsdb.oset()}], False, 5000), ovsdb.select('Bridge', [["_uuid", "==", ovsdb.uuid(bridge_uuid)]], ["datapath_id","name"])) for m in protocol.querywithreply(method, params, connection, self.apiroutine): yield m r = self.apiroutine.jsonrpc_result[0] if 'error' in r: raise JsonRPCErrorResultException('Error while acquiring datapath-id: ' + repr(r['error'])) r = self.apiroutine.jsonrpc_result[1] if 'error' in r: raise JsonRPCErrorResultException('Error while acquiring datapath-id: ' + repr(r['error'])) if r['rows']: r0 = r['rows'][0] name = r0['name'] dpid = int(r0['datapath_id'], 16) if self.bridgenames is None or name in self.bridgenames: self.managed_bridges[connection].append((vhost, dpid, name, bridge_uuid)) self.managed_conns[(vhost, dpid)] = connection for m in self.apiroutine.waitForSend(OVSDBBridgeSetup(OVSDBBridgeSetup.UP, dpid, connection.ovsdb_systemid, name, connection, connection.connmark, vhost, bridge_uuid)): yield m except JsonRPCProtocolException: pass
def _get_bridges(self, connection, protocol): try: try: vhost = protocol.vhost if not hasattr(connection, 'ovsdb_systemid'): method, params = ovsdb.transact( 'Open_vSwitch', ovsdb.select('Open_vSwitch', [], ['external_ids'])) for m in protocol.querywithreply(method, params, connection, self.apiroutine): yield m result = self.apiroutine.jsonrpc_result[0] system_id = ovsdb.omap_getvalue( result['rows'][0]['external_ids'], 'system-id') connection.ovsdb_systemid = system_id else: system_id = connection.ovsdb_systemid if (vhost, system_id) in self.managed_systemids: oc = self.managed_systemids[(vhost, system_id)] ep = _get_endpoint(oc) econns = self.endpoint_conns.get((vhost, ep)) if econns: try: econns.remove(oc) except ValueError: pass del self.managed_systemids[(vhost, system_id)] self.managed_systemids[(vhost, system_id)] = connection self.managed_bridges[connection] = [] ep = _get_endpoint(connection) self.endpoint_conns.setdefault((vhost, ep), []).append(connection) method, params = ovsdb.monitor( 'Open_vSwitch', 'ovsdb_manager_bridges_monitor', {'Bridge': ovsdb.monitor_request(['name', 'datapath_id'])}) try: for m in protocol.querywithreply(method, params, connection, self.apiroutine): yield m except JsonRPCErrorResultException: # The monitor is already set, cancel it first method, params = ovsdb.monitor_cancel( 'ovsdb_manager_bridges_monitor') for m in protocol.querywithreply(method, params, connection, self.apiroutine, False): yield m method, params = ovsdb.monitor( 'Open_vSwitch', 'ovsdb_manager_bridges_monitor', { 'Bridge': ovsdb.monitor_request(['name', 'datapath_id']) }) for m in protocol.querywithreply(method, params, connection, self.apiroutine): yield m except Exception: for m in self.apiroutine.waitForSend( OVSDBConnectionSetup(system_id, connection, connection.connmark, vhost)): yield m raise else: # Process initial bridges init_subprocesses = [] if self.apiroutine.jsonrpc_result and 'Bridge' in self.apiroutine.jsonrpc_result: init_subprocesses = [ self._update_bridge(connection, protocol, buuid, vhost) for buuid in self.apiroutine.jsonrpc_result['Bridge'].keys() ] def init_process(): try: with closing( self.apiroutine.executeAll(init_subprocesses, retnames=())) as g: for m in g: yield m except Exception: for m in self.apiroutine.waitForSend( OVSDBConnectionSetup(system_id, connection, connection.connmark, vhost)): yield m raise else: for m in self.apiroutine.waitForSend( OVSDBConnectionSetup(system_id, connection, connection.connmark, vhost)): yield m self.apiroutine.subroutine(init_process()) # Wait for notify notification = JsonRPCNotificationEvent.createMatcher( 'update', connection, connection.connmark, _ismatch=lambda x: x.params[ 0] == 'ovsdb_manager_bridges_monitor') conn_down = protocol.statematcher(connection) while True: yield (conn_down, notification) if self.apiroutine.matcher is conn_down: break else: for buuid, v in self.apiroutine.event.params[1][ 'Bridge'].items(): # If a bridge's name or datapath-id is changed, we remove this bridge and add it again if 'old' in v: # A bridge is deleted bridges = self.managed_bridges[connection] for i in range(0, len(bridges)): if buuid == bridges[i][3]: self.scheduler.emergesend( OVSDBBridgeSetup( OVSDBBridgeSetup.DOWN, bridges[i][1], system_id, bridges[i][2], connection, connection.connmark, vhost, bridges[i][3], new_datapath_id=int( v['new']['datapath_id'], 16) if 'new' in v and 'datapath_id' in v['new'] else None)) del self.managed_conns[(vhost, bridges[i][1])] del bridges[i] break if 'new' in v: # A bridge is added self.apiroutine.subroutine( self._update_bridge(connection, protocol, buuid, vhost)) except JsonRPCProtocolException: pass finally: del connection._ovsdb_manager_get_bridges
def _get_interface_info(self, connection, protocol, buuid, interface_uuid, port_uuid): try: method, params = ovsdb.transact( 'Open_vSwitch', ovsdb.wait( 'Interface', [["_uuid", "==", ovsdb.uuid(interface_uuid)]], ["ofport"], [{ "ofport": ovsdb.oset() }], False, 5000), ovsdb.wait( 'Interface', [["_uuid", "==", ovsdb.uuid(interface_uuid)]], ["ofport"], [{ "ofport": -1 }], False, 0), ovsdb.wait( 'Interface', [["_uuid", "==", ovsdb.uuid(interface_uuid)]], ["ifindex"], [{ "ifindex": ovsdb.oset() }], False, 5000), ovsdb.select( 'Interface', [["_uuid", "==", ovsdb.uuid(interface_uuid)]], [ "_uuid", "name", "ifindex", "ofport", "type", "external_ids" ])) for m in protocol.querywithreply(method, params, connection, self.apiroutine): yield m r = self.apiroutine.jsonrpc_result[0] if 'error' in r: raise JsonRPCErrorResultException( 'Error while acquiring interface: ' + repr(r['error'])) r = self.apiroutine.jsonrpc_result[1] if 'error' in r: raise JsonRPCErrorResultException( 'Error while acquiring interface: ' + repr(r['error'])) r = self.apiroutine.jsonrpc_result[2] if 'error' in r: # Ignore this port because it is in an error state self.apiroutine.retvalue = [] return r = self.apiroutine.jsonrpc_result[3] if 'error' in r: raise JsonRPCErrorResultException( 'Error while acquiring interface: ' + repr(r['error'])) if not r['rows']: self.apiroutine.retvalue = [] return r0 = r['rows'][0] if r0['ofport'] < 0: # Ignore this port because it is in an error state self.apiroutine.retvalue = [] return r0['_uuid'] = r0['_uuid'][1] r0['ifindex'] = ovsdb.getoptional(r0['ifindex']) r0['external_ids'] = ovsdb.getdict(r0['external_ids']) if buuid not in self.bridge_datapathid: self.apiroutine.retvalue = [] return else: datapath_id = self.bridge_datapathid[buuid] if 'iface-id' in r0['external_ids']: eid = r0['external_ids']['iface-id'] r0['id'] = eid id_ports = self.managed_ids.setdefault((protocol.vhost, eid), []) id_ports.append((datapath_id, r0)) else: r0['id'] = None self.managed_ports.setdefault((protocol.vhost, datapath_id), []).append((port_uuid, r0)) notify = False if (protocol.vhost, datapath_id, r0['ofport']) in self.wait_portnos: notify = True del self.wait_portnos[(protocol.vhost, datapath_id, r0['ofport'])] if (protocol.vhost, datapath_id, r0['name']) in self.wait_names: notify = True del self.wait_names[(protocol.vhost, datapath_id, r0['name'])] if (protocol.vhost, r0['id']) in self.wait_ids: notify = True del self.wait_ids[(protocol.vhost, r0['id'])] if notify: for m in self.apiroutine.waitForSend( OVSDBPortUpNotification(connection, r0['name'], r0['ofport'], r0['id'], protocol.vhost, datapath_id, port=r0)): yield m self.apiroutine.retvalue = [r0] except JsonRPCProtocolException: self.apiroutine.retvalue = []
def _get_bridges(self, connection, protocol): try: try: vhost = protocol.vhost if not hasattr(connection, 'ovsdb_systemid'): method, params = ovsdb.transact('Open_vSwitch', ovsdb.select('Open_vSwitch', [], ['external_ids'])) for m in protocol.querywithreply(method, params, connection, self.apiroutine): yield m result = self.apiroutine.jsonrpc_result[0] system_id = ovsdb.omap_getvalue(result['rows'][0]['external_ids'], 'system-id') connection.ovsdb_systemid = system_id else: system_id = connection.ovsdb_systemid if (vhost, system_id) in self.managed_systemids: oc = self.managed_systemids[(vhost, system_id)] ep = _get_endpoint(oc) econns = self.endpoint_conns.get((vhost, ep)) if econns: try: econns.remove(oc) except ValueError: pass del self.managed_systemids[(vhost, system_id)] self.managed_systemids[(vhost, system_id)] = connection self.managed_bridges[connection] = [] ep = _get_endpoint(connection) self.endpoint_conns.setdefault((vhost, ep), []).append(connection) method, params = ovsdb.monitor('Open_vSwitch', 'ovsdb_manager_bridges_monitor', {'Open_vSwitch':ovsdb.monitor_request(['bridges'])}) for m in protocol.querywithreply(method, params, connection, self.apiroutine): yield m if 'error' in self.apiroutine.jsonrpc_result: # The monitor is already set, cancel it first method, params = ovsdb.monitor_cancel('ovsdb_manager_bridges_monitor') for m in protocol.querywithreply(method, params, connection, self.apiroutine, False): yield m method, params = ovsdb.monitor('Open_vSwitch', 'ovsdb_manager_bridges_monitor', {'Open_vSwitch':ovsdb.monitor_request(['bridges'], True, False, False, True)}) for m in protocol.querywithreply(method, params, connection, self.apiroutine): yield m if 'error' in self.apiroutine.jsonrpc_result: raise JsonRPCErrorResultException('OVSDB request failed: ' + repr(self.apiroutine.jsonrpc_result)) except Exception: for m in self.apiroutine.waitForSend(OVSDBConnectionSetup(system_id, connection, connection.connmark, vhost)): yield m raise else: # Process initial bridges init_subprocesses = [self._update_bridge(connection, protocol, buuid, vhost) for v in self.apiroutine.jsonrpc_result['Open_vSwitch'].values() for _, buuid in ovsdb.getlist(v['new']['bridges'])] def init_process(): try: for m in self.apiroutine.executeAll(init_subprocesses, retnames = ()): yield m except Exception: for m in self.apiroutine.waitForSend(OVSDBConnectionSetup(system_id, connection, connection.connmark, vhost)): yield m raise else: for m in self.apiroutine.waitForSend(OVSDBConnectionSetup(system_id, connection, connection.connmark, vhost)): yield m self.apiroutine.subroutine(init_process()) # Wait for notify notification = JsonRPCNotificationEvent.createMatcher('update', connection, connection.connmark, _ismatch = lambda x: x.params[0] == 'ovsdb_manager_bridges_monitor') conn_down = protocol.statematcher(connection) while True: yield (conn_down, notification) if self.apiroutine.matcher is conn_down: break else: for v in self.apiroutine.event.params[1]['Open_vSwitch'].values(): if 'old' not in v: old = set() else: old = set((oid for _, oid in ovsdb.getlist(v['old']['bridges']))) if 'new' not in v: new = set() else: new = set((oid for _, oid in ovsdb.getlist(v['new']['bridges']))) for buuid in (new - old): self.apiroutine.subroutine(self._update_bridge(connection, protocol, buuid, vhost)) for buuid in (old - new): bridges = self.managed_bridges[connection] for i in range(0, len(bridges)): if buuid == bridges[i][3]: self.scheduler.emergesend(OVSDBBridgeSetup(OVSDBBridgeSetup.DOWN, bridges[i][1], system_id, bridges[i][2], connection, connection.connmark, vhost, bridges[i][3])) del self.managed_conns[(vhost, bridges[i][1])] del bridges[i] break except JsonRPCProtocolException: pass finally: del connection._ovsdb_manager_get_bridges
def _get_bridges(self, connection, protocol): try: try: vhost = protocol.vhost if not hasattr(connection, 'ovsdb_systemid'): method, params = ovsdb.transact('Open_vSwitch', ovsdb.select('Open_vSwitch', [], ['external_ids'])) for m in protocol.querywithreply(method, params, connection, self.apiroutine): yield m result = self.apiroutine.jsonrpc_result[0] system_id = ovsdb.omap_getvalue(result['rows'][0]['external_ids'], 'system-id') connection.ovsdb_systemid = system_id else: system_id = connection.ovsdb_systemid if (vhost, system_id) in self.managed_systemids: oc = self.managed_systemids[(vhost, system_id)] ep = _get_endpoint(oc) econns = self.endpoint_conns.get((vhost, ep)) if econns: try: econns.remove(oc) except ValueError: pass del self.managed_systemids[(vhost, system_id)] self.managed_systemids[(vhost, system_id)] = connection self.managed_bridges[connection] = [] ep = _get_endpoint(connection) self.endpoint_conns.setdefault((vhost, ep), []).append(connection) method, params = ovsdb.monitor('Open_vSwitch', 'ovsdb_manager_bridges_monitor', {'Bridge':ovsdb.monitor_request(['name', 'datapath_id'])}) for m in protocol.querywithreply(method, params, connection, self.apiroutine): yield m if 'error' in self.apiroutine.jsonrpc_result: # The monitor is already set, cancel it first method, params = ovsdb.monitor_cancel('ovsdb_manager_bridges_monitor') for m in protocol.querywithreply(method, params, connection, self.apiroutine, False): yield m method, params = ovsdb.monitor('Open_vSwitch', 'ovsdb_manager_bridges_monitor', {'Bridge':ovsdb.monitor_request(['name', 'datapath_id'])}) for m in protocol.querywithreply(method, params, connection, self.apiroutine): yield m if 'error' in self.apiroutine.jsonrpc_result: raise JsonRPCErrorResultException('OVSDB request failed: ' + repr(self.apiroutine.jsonrpc_result)) except Exception: for m in self.apiroutine.waitForSend(OVSDBConnectionSetup(system_id, connection, connection.connmark, vhost)): yield m raise else: # Process initial bridges init_subprocesses = [self._update_bridge(connection, protocol, buuid, vhost) for buuid in self.apiroutine.jsonrpc_result['Bridge'].keys()] def init_process(): try: with closing(self.apiroutine.executeAll(init_subprocesses, retnames = ())) as g: for m in g: yield m except Exception: for m in self.apiroutine.waitForSend(OVSDBConnectionSetup(system_id, connection, connection.connmark, vhost)): yield m raise else: for m in self.apiroutine.waitForSend(OVSDBConnectionSetup(system_id, connection, connection.connmark, vhost)): yield m self.apiroutine.subroutine(init_process()) # Wait for notify notification = JsonRPCNotificationEvent.createMatcher('update', connection, connection.connmark, _ismatch = lambda x: x.params[0] == 'ovsdb_manager_bridges_monitor') conn_down = protocol.statematcher(connection) while True: yield (conn_down, notification) if self.apiroutine.matcher is conn_down: break else: for buuid, v in self.apiroutine.event.params[1]['Bridge'].items(): # If a bridge's name or datapath-id is changed, we remove this bridge and add it again if 'old' in v: # A bridge is deleted bridges = self.managed_bridges[connection] for i in range(0, len(bridges)): if buuid == bridges[i][3]: self.scheduler.emergesend(OVSDBBridgeSetup(OVSDBBridgeSetup.DOWN, bridges[i][1], system_id, bridges[i][2], connection, connection.connmark, vhost, bridges[i][3], new_datapath_id = int(v['new']['datapath_id'], 16) if 'new' in v and 'datapath_id' in v['new'] else None)) del self.managed_conns[(vhost, bridges[i][1])] del bridges[i] break if 'new' in v: # A bridge is added self.apiroutine.subroutine(self._update_bridge(connection, protocol, buuid, vhost)) except JsonRPCProtocolException: pass finally: del connection._ovsdb_manager_get_bridges
def _get_interface_info(self, connection, protocol, buuid, interface_uuid, port_uuid): try: method, params = ovsdb.transact('Open_vSwitch', ovsdb.wait('Interface', [["_uuid", "==", ovsdb.uuid(interface_uuid)]], ["ofport"], [{"ofport":ovsdb.oset()}], False, 5000), ovsdb.wait('Interface', [["_uuid", "==", ovsdb.uuid(interface_uuid)]], ["ifindex"], [{"ifindex":ovsdb.oset()}], False, 5000), ovsdb.select('Interface', [["_uuid", "==", ovsdb.uuid(interface_uuid)]], ["_uuid", "name", "ifindex", "ofport", "type", "external_ids"])) for m in protocol.querywithreply(method, params, connection, self.apiroutine): yield m r = self.apiroutine.jsonrpc_result[0] if 'error' in r: raise JsonRPCErrorResultException('Error while acquiring interface: ' + repr(r['error'])) r = self.apiroutine.jsonrpc_result[1] if 'error' in r: raise JsonRPCErrorResultException('Error while acquiring interface: ' + repr(r['error'])) r = self.apiroutine.jsonrpc_result[2] if 'error' in r: raise JsonRPCErrorResultException('Error while acquiring interface: ' + repr(r['error'])) if not r['rows']: self.apiroutine.retvalue = [] return r0 = r['rows'][0] if r0['ofport'] < 0: # Ignore this port because it is in an error state self.apiroutine.retvalue = [] return r0['_uuid'] = r0['_uuid'][1] r0['ifindex'] = ovsdb.getoptional(r0['ifindex']) r0['external_ids'] = ovsdb.getdict(r0['external_ids']) if buuid not in self.bridge_datapathid: self.apiroutine.retvalue = [] return else: datapath_id = self.bridge_datapathid[buuid] if 'iface-id' in r0['external_ids']: eid = r0['external_ids']['iface-id'] r0['id'] = eid id_ports = self.managed_ids.setdefault((protocol.vhost, eid), []) id_ports.append((datapath_id, r0)) else: r0['id'] = None self.managed_ports.setdefault((protocol.vhost, datapath_id),[]).append((port_uuid, r0)) notify = False if (protocol.vhost, datapath_id, r0['ofport']) in self.wait_portnos: notify = True del self.wait_portnos[(protocol.vhost, datapath_id, r0['ofport'])] if (protocol.vhost, datapath_id, r0['name']) in self.wait_names: notify = True del self.wait_names[(protocol.vhost, datapath_id, r0['name'])] if (protocol.vhost, r0['id']) in self.wait_ids: notify = True del self.wait_ids[(protocol.vhost, r0['id'])] if notify: for m in self.apiroutine.waitForSend(OVSDBPortUpNotification(connection, r0['name'], r0['ofport'], r0['id'], protocol.vhost, datapath_id, port = r0)): yield m self.apiroutine.retvalue = [r0] except JsonRPCProtocolException: self.apiroutine.retvalue = []