def test_get_ucast_mac_remote_by_mac_and_ls_when_not_found(self): record_dict = self._get_ucast_mac_remote_dict() record_dict['mac'] = '00:11:22:33:44:55:66' record_dict['logical_switch_uuid'] = 'ls123' result = lib.get_ucast_mac_remote_by_mac_and_ls(self.ctx, record_dict) self.assertEqual(result, None)
def test_get_ucast_mac_remote_by_mac_and_ls(self): record_dict = self._get_ucast_mac_remote_dict() with self.ctx.session.begin(subtransactions=True): entry = self._create_ucast_mac_remote(record_dict, '00:11:22:33:44:55:66', 'ls123') record_dict['mac'] = '00:11:22:33:44:55:66' record_dict['logical_switch_uuid'] = 'ls123' result = lib.get_ucast_mac_remote_by_mac_and_ls(self.ctx, record_dict) self.assertEqual(entry, result)
def test_get_ucast_mac_remote_by_mac_and_ls(self): record_dict = self._get_ucast_mac_remote_dict() with self.ctx.session.begin(subtransactions=True): entry = self._create_ucast_mac_remote(record_dict, '00:11:22:33:44:55:66', 'ls123') record_dict['mac'] = '00:11:22:33:44:55:66' record_dict['logical_switch_uuid'] = 'ls123' result = lib.get_ucast_mac_remote_by_mac_and_ls(self.ctx, record_dict) self.assertEqual(entry, result)
def create_l2_gateway_connection(self, context, l2_gateway_connection): """Process the call from the CLI and trigger the RPC, to update the connection to the gateway. """ u_mac_dict = {} ls_dict = {} mac_dict = {} is_mac = False self._admin_check(context, 'CREATE') gw_connection = l2_gateway_connection.get('l2_gateway_connection') # validate connection self._validate_connection(context, gw_connection) # get l2 gateway devices l2gateway_devices = self.get_l2gateway_devices_by_gateway_id( context, gw_connection.get('l2_gateway_id')) for device in l2gateway_devices: locator_list = [] ovsdb_identifier, logical_switch, port_dict = ( self._process_port_list(context, device, gw_connection, "CREATE")) ls_dict = self._get_logical_switch_dict( context, logical_switch, gw_connection) ports = self._get_port_details(context, gw_connection.get('network_id')) if not is_mac: is_mac = True for port in ports: mac_list = [] if port['device_owner']: dst_ip, ip_address = self._get_ip_details(context, port) mac_remote = self._get_dict( ovsdb_schema.UcastMacsRemote( uuid=None, mac=port.get('mac_address'), logical_switch_id=None, physical_locator_id=None, ip_address=ip_address)) if logical_switch: u_mac_dict['mac'] = port.get('mac_address') u_mac_dict['ovsdb_identifier'] = ovsdb_identifier u_mac_dict['logical_switch_uuid'] = ( logical_switch.get('uuid')) ucast_mac_remote = ( db.get_ucast_mac_remote_by_mac_and_ls( context, u_mac_dict)) if not ucast_mac_remote: mac_list.append(mac_remote) else: mac_list.append(mac_remote) locator_list = self._get_locator_list( context, dst_ip, ovsdb_identifier, mac_list, locator_list) for locator in locator_list: mac_dict[locator.get('dst_ip')] = locator.pop('macs') locator.pop('ovsdb_identifier') self.agent_rpc.update_connection_to_gateway( context, ovsdb_identifier, ls_dict, locator_list, mac_dict, port_dict) return super(L2GatewayPlugin, self).create_l2_gateway_connection( context, l2_gateway_connection)
def delete_port_mac(self, context, port): """Process the deleted port and trigger the RPC to delete from the gateway. When the ML2 plugin invokes this call, the argument port is a single port dict, whereas the L2gateway service plugin sends it as a list of port dicts. """ ls_dict = {} mac_list = [] logical_switches = [] ovsdb_identifier = None if isinstance(port, list): from_l2gw_plugin = True network_id = port[0].get('network_id') ovsdb_identifier = port[0].get('ovsdb_identifier') lg_dict = {'logical_switch_name': network_id, 'ovsdb_identifier': ovsdb_identifier} logical_switch = db.get_logical_switch_by_name( context, lg_dict) logical_switches.append(logical_switch) port_list = port else: from_l2gw_plugin = False network_id = port.get('network_id') logical_switches = ( db.get_all_logical_switches_by_name( context, network_id)) l2gateway_connections = self.get_l2_gateway_connections( context, filters={'network_id': [network_id]}) if not l2gateway_connections: return port_list = [port] for port_dict in port_list: if port_dict['device_owner']: if logical_switches: for logical_switch in logical_switches: logical_switch_uuid = logical_switch.get('uuid') mac = port_dict.get("mac_address") if port_dict.get('ovsdb_identifier', None): ovsdb_identifier = port_dict.get( 'ovsdb_identifier') else: ovsdb_identifier = logical_switch.get( 'ovsdb_identifier') record_dict = {'mac': mac, 'logical_switch_uuid': logical_switch_uuid, 'ovsdb_identifier': ovsdb_identifier} rec_dict = {'logical_switch_id': logical_switch_uuid, 'ovsdb_identifier': ovsdb_identifier} if len(db.get_all_vlan_bindings_by_logical_switch( context, rec_dict)) > 1: if from_l2gw_plugin: ls = logical_switch.get('name') l2gateway_connections = ( self.get_l2_gateway_connections( context, filters={'network_id': [ls]})) if len(l2gateway_connections) > 1: continue ucast_mac_remote = ( db.get_ucast_mac_remote_by_mac_and_ls( context, record_dict)) del_count = 0 if not ucast_mac_remote: LOG.debug("delete_port_mac: MAC %s does" " not exist", mac) # It is possible that this MAC is present # in the pending_ucast_mac_remote table. # Delete this MAC as it was not inserted # into the OVSDB server earlier. del_count = db.delete_pending_ucast_mac_remote( context, 'insert', ovsdb_identifier, logical_switch_uuid, mac) if not del_count: mac_list = ls_dict.get(logical_switch_uuid, []) mac_list.append(mac) ls_dict[logical_switch_uuid] = mac_list else: LOG.debug("delete_port_mac:Logical Switch %s " "does not exist ", port_dict.get('network_id')) return for logical_switch_uuid, mac_list in ls_dict.items(): try: if mac_list: self.agent_rpc.delete_vif_from_gateway(context, ovsdb_identifier, logical_switch_uuid, mac_list) except messaging.MessagingTimeout: # If RPC is timed out, then the RabbitMQ # will retry the operation. LOG.exception(_LE("Communication error with " "the L2 gateway agent")) except Exception as ex: # The remote OVSDB server may be down. # We need to retry this operation later. LOG.debug("Exception occurred %s", str(ex)) db.add_pending_ucast_mac_remote( context, 'delete', ovsdb_identifier, logical_switch_uuid, None, mac_list)
def add_port_mac(self, context, port_dict): """Process the created port and trigger the RPC to add to the gateway. """ port_id = port_dict.get("id") port = self._core_plugin.get_port(context, port_id) if port['device_owner']: network_id = port.get("network_id") dst_ip, ip_address = self._get_ip_details(context, port) network = self._get_network_details(context, network_id) l2gateway_connections = self.get_l2_gateway_connections( context, filters={'network_id': [network_id]}) if not l2gateway_connections: return logical_switches = db.get_all_logical_switches_by_name(context, network_id) if not logical_switches: return for logical_switch in logical_switches: logical_switch['description'] = network.get('name') ovsdb_identifier = logical_switch.get('ovsdb_identifier') locator_dict = {'dst_ip': dst_ip, 'ovsdb_identifier': ovsdb_identifier} physical_locator = self._form_physical_locator_schema( context, locator_dict) locator_uuid = physical_locator.get('uuid') logical_switch_uuid = logical_switch.get('uuid') mac_remote = self._get_dict(ovsdb_schema.UcastMacsRemote( uuid=None, mac=port['mac_address'], logical_switch_id=logical_switch_uuid, physical_locator_id=locator_uuid, ip_address=ip_address)) mac_dict = mac_remote mac_dict['ovsdb_identifier'] = ovsdb_identifier mac_dict['logical_switch_uuid'] = logical_switch_uuid ucast_mac_remote = db.get_ucast_mac_remote_by_mac_and_ls( context, mac_dict) if ucast_mac_remote: # check whether locator got changed in vm migration if ucast_mac_remote['physical_locator_id' ] != physical_locator['uuid']: mac_remote['uuid'] = ucast_mac_remote['uuid'] try: self.agent_rpc.update_vif_to_gateway( context, ovsdb_identifier, physical_locator, mac_remote) LOG.debug( "VM migrated from %s to %s. Update" "locator in Ucast_Macs_Remote", ucast_mac_remote['physical_locator_id'], physical_locator['uuid']) except messaging.MessagingTimeout: # If RPC is timed out, then the RabbitMQ # will retry the operation. LOG.exception(_LE("Communication error with " "the L2 gateway agent")) except Exception: # The remote OVSDB server may be down. # We need to retry this operation later. db.add_pending_ucast_mac_remote( context, 'update', ovsdb_identifier, logical_switch_uuid, physical_locator, [mac_remote]) else: LOG.debug("add_port_mac: MAC %s exists " "in Gateway", mac_dict['mac']) ovsdb_data_handler = ( self.ovsdb_callback.get_ovsdbdata_object( ovsdb_identifier)) ovsdb_data_handler._handle_l2pop( context, [ucast_mac_remote]) continue # else it is a new port created try: self.agent_rpc.add_vif_to_gateway( context, ovsdb_identifier, logical_switch, physical_locator, mac_remote) except messaging.MessagingTimeout: # If RPC is timed out, then the RabbitMQ # will retry the operation. LOG.exception(_LE("Communication error with " "the L2 gateway agent")) except Exception: # The remote OVSDB server may be down. # We need to retry this operation later. LOG.debug("The remote OVSDB server may be down") db.add_pending_ucast_mac_remote( context, 'insert', ovsdb_identifier, logical_switch_uuid, physical_locator, [mac_remote])
def create_l2_gateway_connection(self, context, l2_gateway_connection): """Process the call from the CLI and trigger the RPC, to update the connection to the gateway. """ u_mac_dict = {} ls_dict = {} mac_dict = {} self.service_plugin._admin_check(context, 'CREATE') gw_connection = l2_gateway_connection.get('l2_gateway_connection') # validate connection self._validate_connection(context, gw_connection) # get l2 gateway devices l2gateway_devices = ( self.service_plugin.get_l2gateway_devices_by_gateway_id( context, gw_connection.get('l2_gateway_id'))) for device in l2gateway_devices: locator_list = [] ovsdb_identifier, logical_switch, port_dict = ( self._process_port_list(context, device, gw_connection, "CREATE")) ls_dict = self._get_logical_switch_dict( context, logical_switch, gw_connection) ports = self._get_port_details(context, gw_connection.get('network_id')) for port in ports: mac_list = [] if port['device_owner']: dst_ip, ip_address = self._get_ip_details(context, port) mac_ip_pairs = [] if isinstance(port.get("allowed_address_pairs"), list): for address_pair in port['allowed_address_pairs']: mac = address_pair['mac_address'] mac_ip_pairs.append((mac, address_pair['ip_address'])) mac_ip_pairs.append((port.get('mac_address'), ip_address)) for mac, ip in mac_ip_pairs: mac_remote = self._get_dict( ovsdb_schema.UcastMacsRemote( uuid=None, mac=mac, logical_switch_id=None, physical_locator_id=None, ip_address=ip)) if logical_switch: u_mac_dict['mac'] = mac u_mac_dict['ovsdb_identifier'] = ovsdb_identifier u_mac_dict['logical_switch_uuid'] = ( logical_switch.get('uuid')) ucast_mac_remote = ( db.get_ucast_mac_remote_by_mac_and_ls( context, u_mac_dict)) if not ucast_mac_remote: mac_list.append(mac_remote) else: mac_list.append(mac_remote) locator_list = self._get_locator_list( context, dst_ip, ovsdb_identifier, mac_list, locator_list) for locator in locator_list: mac_dict[locator.get('dst_ip')] = locator.pop('macs') locator.pop('ovsdb_identifier') self.agent_rpc.update_connection_to_gateway( context, ovsdb_identifier, ls_dict, locator_list, mac_dict, port_dict, 'CREATE')
def update_l2_gateway_postcommit(self, context, l2_gateway): """Process the call from the CLI and trigger the RPC, to update the connection of the gateway. """ self.service_plugin._admin_check(context, 'UPDATE') # get l2 gateway devices l2gateway_devices = ( self.service_plugin.get_l2gateway_devices_by_gateway_id( context, l2_gateway['id'])) # get l2 gateway connections gw_connections = self.service_plugin._get_l2_gateway_connections( context) for gw_connection in gw_connections: u_mac_dict = {} mac_dict = {} for device in l2gateway_devices: locator_list = [] ovsdb_identifier, logical_switch, port_dict = ( self._process_port_list(context, device, gw_connection, "UPDATE")) ls_dict = self._get_logical_switch_dict( context, logical_switch, gw_connection) port_dict_before_update_con = \ [port for port in self.port_dict_before_update if port['vlan_bindings'][0]['logical_switch_uuid'] == logical_switch['uuid']] port_dict_add = \ [port for port in port_dict if port not in port_dict_before_update_con] port_dict_delete = \ [port for port in port_dict_before_update_con if port not in port_dict] if port_dict_add: ports = self._get_port_details( context, gw_connection.get('network_id')) LOG.debug("L2gwRpcDriver.update_l2_gw: ports=%s", ports) for port in ports: mac_list = [] if port['device_owner']: dst_ip, ip_address = self._get_ip_details(context, port) mac_ip_pairs = [] if isinstance( port.get("allowed_address_pairs"), list): for address_pair in \ port['allowed_address_pairs']: mac = address_pair['mac_address'] mac_ip_pairs.append( (mac, address_pair['ip_address'])) mac_ip_pairs.append((port.get('mac_address'), ip_address)) for mac, ip in mac_ip_pairs: mac_remote = self._get_dict( ovsdb_schema.UcastMacsRemote( uuid=None, mac=mac, logical_switch_id=None, physical_locator_id=None, ip_address=ip)) if logical_switch: u_mac_dict['mac'] = mac u_mac_dict['ovsdb_identifier'] = \ ovsdb_identifier u_mac_dict['logical_switch_uuid'] = ( logical_switch.get('uuid')) ucast_mac_remote = ( db.get_ucast_mac_remote_by_mac_and_ls( context, u_mac_dict)) if not ucast_mac_remote: mac_list.append(mac_remote) else: mac_list.append(mac_remote) locator_list = self._get_locator_list( context, dst_ip, ovsdb_identifier, mac_list, locator_list) for locator in locator_list: mac_dict[locator.get('dst_ip')] = locator.pop('macs') locator.pop('ovsdb_identifier') self.agent_rpc.update_connection_to_gateway( context, ovsdb_identifier, ls_dict, locator_list, mac_dict, port_dict_add, 'CREATE') if port_dict_delete: self.agent_rpc.update_connection_to_gateway( context, ovsdb_identifier, ls_dict, locator_list, mac_dict, port_dict_delete, 'DELETE')
def create_l2_gateway_connection(self, context, l2_gateway_connection): """Process the call from the CLI and trigger the RPC, to update the connection to the gateway. """ u_mac_dict = {} ls_dict = {} mac_dict = {} self.service_plugin._admin_check(context, 'CREATE') gw_connection = l2_gateway_connection.get('l2_gateway_connection') # validate connection self._validate_connection(context, gw_connection) # get l2 gateway devices l2gateway_devices = ( self.service_plugin.get_l2gateway_devices_by_gateway_id( context, gw_connection.get('l2_gateway_id'))) for device in l2gateway_devices: locator_list = [] ovsdb_identifier, logical_switch, port_dict = ( self._process_port_list(context, device, gw_connection, "CREATE")) ls_dict = self._get_logical_switch_dict(context, logical_switch, gw_connection) ports = self._get_port_details(context, gw_connection.get('network_id')) for port in ports: mac_list = [] if port['device_owner']: dst_ip, ip_address = self._get_ip_details(context, port) mac_ip_pairs = [] if isinstance(port.get("allowed_address_pairs"), list): for address_pair in port['allowed_address_pairs']: mac = address_pair['mac_address'] mac_ip_pairs.append( (mac, address_pair['ip_address'])) mac_ip_pairs.append((port.get('mac_address'), ip_address)) for mac, ip in mac_ip_pairs: mac_remote = self._get_dict( ovsdb_schema.UcastMacsRemote( uuid=None, mac=mac, logical_switch_id=None, physical_locator_id=None, ip_address=ip)) if logical_switch: u_mac_dict['mac'] = mac u_mac_dict['ovsdb_identifier'] = ovsdb_identifier u_mac_dict['logical_switch_uuid'] = ( logical_switch.get('uuid')) ucast_mac_remote = ( db.get_ucast_mac_remote_by_mac_and_ls( context, u_mac_dict)) if not ucast_mac_remote: mac_list.append(mac_remote) else: mac_list.append(mac_remote) locator_list = self._get_locator_list( context, dst_ip, ovsdb_identifier, mac_list, locator_list) for locator in locator_list: mac_dict[locator.get('dst_ip')] = locator.pop('macs') locator.pop('ovsdb_identifier') self.agent_rpc.update_connection_to_gateway( context, ovsdb_identifier, ls_dict, locator_list, mac_dict, port_dict, 'CREATE')
def update_l2_gateway_postcommit(self, context, l2_gateway): """Process the call from the CLI and trigger the RPC, to update the connection of the gateway. """ self.service_plugin._admin_check(context, 'UPDATE') # get l2 gateway devices l2gateway_devices = ( self.service_plugin.get_l2gateway_devices_by_gateway_id( context, l2_gateway['id'])) # get l2 gateway connections gw_connections = self.service_plugin._get_l2_gateway_connections( context) for gw_connection in gw_connections: u_mac_dict = {} mac_dict = {} for device in l2gateway_devices: locator_list = [] ovsdb_identifier, logical_switch, port_dict = ( self._process_port_list(context, device, gw_connection, "UPDATE")) ls_dict = self._get_logical_switch_dict( context, logical_switch, gw_connection) port_dict_before_update_con = \ [port for port in self.port_dict_before_update if port['vlan_bindings'][0]['logical_switch_uuid'] == logical_switch['uuid']] port_dict_add = \ [port for port in port_dict if port not in port_dict_before_update_con] port_dict_delete = \ [port for port in port_dict_before_update_con if port not in port_dict] if port_dict_add: ports = self._get_port_details( context, gw_connection.get('network_id')) LOG.debug("L2gwRpcDriver.update_l2_gw: ports=%s", ports) for port in ports: mac_list = [] if port['device_owner']: dst_ip, ip_address = self._get_ip_details( context, port) mac_ip_pairs = [] if isinstance(port.get("allowed_address_pairs"), list): for address_pair in \ port['allowed_address_pairs']: mac = address_pair['mac_address'] mac_ip_pairs.append( (mac, address_pair['ip_address'])) mac_ip_pairs.append( (port.get('mac_address'), ip_address)) for mac, ip in mac_ip_pairs: mac_remote = self._get_dict( ovsdb_schema.UcastMacsRemote( uuid=None, mac=mac, logical_switch_id=None, physical_locator_id=None, ip_address=ip)) if logical_switch: u_mac_dict['mac'] = mac u_mac_dict['ovsdb_identifier'] = \ ovsdb_identifier u_mac_dict['logical_switch_uuid'] = ( logical_switch.get('uuid')) ucast_mac_remote = ( db.get_ucast_mac_remote_by_mac_and_ls( context, u_mac_dict)) if not ucast_mac_remote: mac_list.append(mac_remote) else: mac_list.append(mac_remote) locator_list = self._get_locator_list( context, dst_ip, ovsdb_identifier, mac_list, locator_list) for locator in locator_list: mac_dict[locator.get('dst_ip')] = locator.pop('macs') locator.pop('ovsdb_identifier') self.agent_rpc.update_connection_to_gateway( context, ovsdb_identifier, ls_dict, locator_list, mac_dict, port_dict_add, 'CREATE') if port_dict_delete: self.agent_rpc.update_connection_to_gateway( context, ovsdb_identifier, ls_dict, locator_list, mac_dict, port_dict_delete, 'DELETE')