def _test_del_arp_table_entry_non_tunnel(self, network_type): self._prepare_l2_pop_ofports(network_type=network_type) fdb_entry = { self.lvms[0].net: { 'network_type': network_type, 'segment_id': 'tun1', 'ports': { self.lvms[0].ip: [FLOODING_ENTRY, l2pop_rpc.PortInfo('mac1', 'ip1')], self.lvms[1].ip: [l2pop_rpc.PortInfo('mac2', 'ip2')], '192.0.2.1': [FLOODING_ENTRY, l2pop_rpc.PortInfo('mac3', 'ip3')] } } } with mock.patch.object(self.agent, 'cleanup_tunnel_port') as cleanup_tun_fn: self.agent.fdb_remove(None, fdb_entry) calls = [ mock.call(self.agent.local_vlan_map[self.lvms[0].net].vlan, 'ip1'), mock.call(self.agent.local_vlan_map[self.lvms[0].net].vlan, 'ip2') ] self.ryuapp.del_arp_table_entry.assert_has_calls(calls, any_order=True) self.assertFalse(cleanup_tun_fn.called)
def test_add_arp_table_entry(self): self._prepare_l2_pop_ofports() fdb_entry = { self.lvms[0].net: { 'network_type': self.tunnel_type, 'segment_id': 'tun1', 'ports': { self.lvms[0].ip: [FLOODING_ENTRY, l2pop_rpc.PortInfo('mac1', 'ip1')], self.lvms[1].ip: [l2pop_rpc.PortInfo('mac2', 'ip2')], '192.0.2.1': [FLOODING_ENTRY, l2pop_rpc.PortInfo('mac3', 'ip3')] } } } with mock.patch.object(self.agent, 'setup_tunnel_port') as setup_tun_fn: self.agent.fdb_add(None, fdb_entry) calls = [ mock.call(self.agent.local_vlan_map[self.lvms[0].net].vlan, 'ip1', 'mac1'), mock.call(self.agent.local_vlan_map[self.lvms[0].net].vlan, 'ip2', 'mac2') ] self.ryuapp.add_arp_table_entry.assert_has_calls(calls, any_order=True) setup_tun_fn.assert_called_once_with(self.agent.int_br, '192.0.2.1', 'gre')
def _fixed_ips_changed(self, context, orig, port, diff_ips): orig_ips, port_ips = diff_ips if (port['device_owner'] == const.DEVICE_OWNER_DVR_INTERFACE): agent_host = context.host else: agent_host = context.original_host if not agent_host: return agent_ip = l2pop_db.get_agent_ip_by_host(context._plugin_context, agent_host) orig_mac_ip = [l2pop_rpc.PortInfo(mac_address=port['mac_address'], ip_address=ip) for ip in orig_ips] port_mac_ip = [l2pop_rpc.PortInfo(mac_address=port['mac_address'], ip_address=ip) for ip in port_ips] upd_fdb_entries = {port['network_id']: {agent_ip: {}}} ports = upd_fdb_entries[port['network_id']][agent_ip] if orig_mac_ip: ports['before'] = orig_mac_ip if port_mac_ip: ports['after'] = port_mac_ip self.L2populationAgentNotify.update_fdb_entries( self.rpc_ctx, {'chg_ip': upd_fdb_entries}) return True
def test_fdb_add_called_two_networks(self): self._register_ml2_agents() with self.subnet(network=self._network) as subnet: host_arg = {portbindings.HOST_ID: HOST + '_2'} with self.port(subnet=subnet, device_owner=DEVICE_OWNER_COMPUTE, arg_list=(portbindings.HOST_ID,), **host_arg) as port1: with self.subnet(cidr='10.1.0.0/24') as subnet2: with self.port(subnet=subnet2, device_owner=DEVICE_OWNER_COMPUTE, arg_list=(portbindings.HOST_ID,), **host_arg): host_arg = {portbindings.HOST_ID: HOST} with self.port(subnet=subnet, device_owner=DEVICE_OWNER_COMPUTE, arg_list=(portbindings.HOST_ID,), **host_arg) as port3: p1 = port1['port'] p3 = port3['port'] device = 'tap' + p3['id'] self.mock_cast.reset_mock() self.mock_fanout.reset_mock() self.callbacks.update_device_up( self.adminContext, agent_id=HOST, device=device) p1_ips = [p['ip_address'] for p in p1['fixed_ips']] expected1 = {p1['network_id']: {'ports': {'20.0.0.2': [constants.FLOODING_ENTRY, l2pop_rpc.PortInfo( p1['mac_address'], p1_ips[0])]}, 'network_type': 'vxlan', 'segment_id': 1}} self.mock_cast.assert_called_with( mock.ANY, 'add_fdb_entries', expected1, HOST) p3_ips = [p['ip_address'] for p in p3['fixed_ips']] expected2 = {p1['network_id']: {'ports': {'20.0.0.1': [constants.FLOODING_ENTRY, l2pop_rpc.PortInfo( p3['mac_address'], p3_ips[0])]}, 'network_type': 'vxlan', 'segment_id': 1}} self.mock_fanout.assert_called_with( mock.ANY, 'add_fdb_entries', expected2)
def test_port_info_compare(self): # An assumption the code makes is that PortInfo compares equal to # equivalent regular tuples. self.assertEqual(("mac", "ip"), l2pop_rpc.PortInfo("mac", "ip")) flooding_entry = l2pop_rpc.PortInfo(*constants.FLOODING_ENTRY) self.assertEqual(constants.FLOODING_ENTRY, flooding_entry)
def test_mac_addr_changed(self): self._register_ml2_agents() with self.subnet(network=self._network) as subnet: host_arg = {portbindings.HOST_ID: HOST + '_5'} with self.port(subnet=subnet, device_owner=DEVICE_OWNER_COMPUTE, arg_list=(portbindings.HOST_ID, ), **host_arg) as port1: p1 = port1['port'] self.mock_fanout.reset_mock() device = 'tap' + p1['id'] old_mac = p1['mac_address'] mac = old_mac.split(':') mac[5] = '01' if mac[5] != '01' else '00' new_mac = ':'.join(mac) data = { 'port': { 'mac_address': new_mac, portbindings.HOST_ID: HOST } } req = self.new_update_request('ports', data, p1['id']) res = self.deserialize(self.fmt, req.get_response(self.api)) self.assertIn('port', res) self.assertEqual(new_mac, res['port']['mac_address']) # port was not bound before, so no fdb call expected yet self.assertFalse(self.mock_fanout.called) self.callbacks.update_device_up(self.adminContext, agent_id=HOST, device=device) self.assertEqual(1, self.mock_fanout.call_count) add_expected = { p1['network_id']: { 'segment_id': 1, 'network_type': 'vxlan', 'ports': { '20.0.0.1': [ l2pop_rpc.PortInfo('00:00:00:00:00:00', '0.0.0.0'), l2pop_rpc.PortInfo(new_mac, '10.0.0.2') ] } } } self.mock_fanout.assert_called_with(mock.ANY, 'add_fdb_entries', add_expected)
def test_fdb_add_called_dualstack(self): self._register_ml2_agents() host_arg = {portbindings.HOST_ID: HOST, 'admin_state_up': True} with self.subnet(self._network) as subnet,\ self.subnet( self._network, cidr='2001:db8::/64', ip_version=6, gateway_ip='fe80::1', ipv6_address_mode=n_const.IPV6_SLAAC) as subnet2: with self.port(subnet, fixed_ips=[{ 'subnet_id': subnet['subnet']['id'] }, { 'subnet_id': subnet2['subnet']['id'] }], device_owner=DEVICE_OWNER_COMPUTE, arg_list=(portbindings.HOST_ID, ), **host_arg) as port: p1 = port['port'] device = 'tap' + p1['id'] self.mock_fanout.reset_mock() self.callbacks.update_device_up(self.adminContext, agent_id=HOST, device=device) p1_ips = [p['ip_address'] for p in p1['fixed_ips']] expected = { p1['network_id']: { 'ports': { '20.0.0.1': [ constants.FLOODING_ENTRY, l2pop_rpc.PortInfo(p1['mac_address'], p1_ips[0]), l2pop_rpc.PortInfo(p1['mac_address'], p1_ips[1]) ] }, 'network_type': 'vxlan', 'segment_id': 1 } } self.mock_fanout.assert_called_with(mock.ANY, 'add_fdb_entries', expected)
def test_fdb_add_port(self): self._prepare_l2_pop_ofports() tunnel_ip = '10.10.10.10' fdb_entry = {self.lvms[0].net: {'network_type': self.tunnel_type, 'segment_id': 'tun1', 'ports': {self.lvms[0].ip: [l2pop_rpc.PortInfo('mac', 'ip')]}}} with mock.patch.object(self.agent, '_setup_tunnel_port') as add_tun_fn: self.agent.fdb_add(None, fdb_entry) self.assertFalse(add_tun_fn.called) fdb_entry[self.lvms[0].net]['ports'][tunnel_ip] = [ l2pop_rpc.PortInfo('mac', 'ip')] self.agent.fdb_add(None, fdb_entry) self.assertFalse(add_tun_fn.called)
def test_create_agent_fdb(self): binding = mock.Mock() binding.port = { 'mac_address': '00:00:DE:AD:BE:EF', 'fixed_ips': [{ 'ip_address': '1.1.1.1' }] } fdb_network_ports, fdb_agent = (self._mock_network_ports( HOST + '2', binding)) agent_ips = {fdb_agent: '20.0.0.1'} agent_fdb = self._test_create_agent_fdb(fdb_network_ports, agent_ips) result = agent_fdb['network_id'] expected_result = { 'segment_id': 1, 'network_type': 'vxlan', 'ports': { '10.0.0.1': [constants.FLOODING_ENTRY], '20.0.0.1': [ constants.FLOODING_ENTRY, l2pop_rpc.PortInfo(mac_address='00:00:DE:AD:BE:EF', ip_address='1.1.1.1') ] } } self.assertEqual(expected_result, result)
def test_fdb_add_flows(self): self._prepare_l2_pop_ofports() fdb_entry = { self.lvms[0].net: { 'network_type': self.tunnel_type, 'segment_id': 'tun1', 'ports': { self.lvms[1].ip: [l2pop_rpc.PortInfo('mac', 'ip'), FLOODING_ENTRY] } } } with contextlib.nested( mock.patch.object(self.agent, '_setup_tunnel_port'), mock.patch.object(self.agent.int_br, 'install_tunnel_output'), mock.patch.object(self.agent.int_br, 'delete_tunnel_output'), ) as (add_tun_fn, install_fn, delete_fn): add_tun_fn.return_value = 2 self.agent.fdb_add(None, fdb_entry) self.assertEqual(2, install_fn.call_count) expected_calls = [ mock.call(7, 11, 21, set([2]), eth_dst='mac', goto_next=False), mock.call(10, 11, 21, set([1, 2]), goto_next=True) ] install_fn.assert_has_calls(expected_calls) self.assertFalse(delete_fn.called)
def test_host_changed_twice(self): self._register_ml2_agents() with self.subnet(network=self._network) as subnet: host_arg = {portbindings.HOST_ID: L2_AGENT['host']} host2_arg = {portbindings.HOST_ID: L2_AGENT_2['host']} with self.port(subnet=subnet, cidr='10.0.0.0/24', device_owner=DEVICE_OWNER_COMPUTE, arg_list=(portbindings.HOST_ID, ), **host_arg) as port1: with self.port(subnet=subnet, cidr='10.0.0.0/24', device_owner=DEVICE_OWNER_COMPUTE, arg_list=(portbindings.HOST_ID, ), **host2_arg) as port2: p1 = port1['port'] device1 = 'tap' + p1['id'] self.callbacks.update_device_up(self.adminContext, agent_id=L2_AGENT['host'], device=device1) p2 = port2['port'] device2 = 'tap' + p2['id'] self.callbacks.update_device_up( self.adminContext, agent_id=L2_AGENT_2['host'], device=device2) data2 = {'port': {'binding:host_id': L2_AGENT_2['host']}} req = self.new_update_request('ports', data2, p1['id']) res = self.deserialize(self.fmt, req.get_response(self.api)) self.assertEqual(res['port']['binding:host_id'], L2_AGENT_2['host']) data4 = {'port': {'binding:host_id': L2_AGENT_4['host']}} req = self.new_update_request('ports', data4, p1['id']) res = self.deserialize(self.fmt, req.get_response(self.api)) self.assertEqual(res['port']['binding:host_id'], L2_AGENT_4['host']) self.mock_fanout.reset_mock() self.callbacks.get_device_details( self.adminContext, device=device1, agent_id=L2_AGENT_4['host']) p1_ips = [p['ip_address'] for p in p1['fixed_ips']] expected = { p1['network_id']: { 'ports': { '20.0.0.1': [ constants.FLOODING_ENTRY, l2pop_rpc.PortInfo(p1['mac_address'], p1_ips[0]) ] }, 'network_type': 'vxlan', 'segment_id': 1 } } self.mock_fanout.assert_called_with( mock.ANY, 'remove_fdb_entries', expected)
def _get_port_infos(self, port, segment, agent_host): if not agent_host: return session = db_api.get_session() agent = l2pop_db.get_agent_by_host(session, agent_host) if not agent: return agent_ip = l2pop_db.get_agent_ip(agent) if not agent_ip: LOG.warning(_LW("Unable to retrieve the agent ip, check the agent " "configuration.")) return if not segment: LOG.warning(_LW("Port %(port)s updated by agent %(agent)s " "isn't bound to any segment"), {'port': port['id'], 'agent': agent}) return network_types = l2pop_db.get_agent_l2pop_network_types(agent) if network_types is None: network_types = l2pop_db.get_agent_tunnel_types(agent) if segment['network_type'] not in network_types: return fdb_entries = [l2pop_rpc.PortInfo(mac_address=port['mac_address'], ip_address=ip['ip_address']) for ip in port['fixed_ips']] return agent_ip, fdb_entries
def test_fdb_add_called_for_l2pop_network_types(self): self._register_ml2_agents() host = HOST + '_5' with self.subnet(network=self._network2) as subnet: host_arg = {portbindings.HOST_ID: host} with self.port(subnet=subnet, device_owner=DEVICE_OWNER_COMPUTE, arg_list=(portbindings.HOST_ID,), **host_arg) as port1: with self.port(subnet=subnet, arg_list=(portbindings.HOST_ID,), **host_arg): p1 = port1['port'] device = 'tap' + p1['id'] self.mock_fanout.reset_mock() self.callbacks.update_device_up(self.adminContext, agent_id=host, device=device) p1_ips = [p['ip_address'] for p in p1['fixed_ips']] expected = {p1['network_id']: {'ports': {'20.0.0.5': [constants.FLOODING_ENTRY, l2pop_rpc.PortInfo( p1['mac_address'], p1_ips[0])]}, 'network_type': 'vlan', 'segment_id': 2}} self.mock_fanout.assert_called_with( mock.ANY, 'add_fdb_entries', expected)
def test_delete_port_last_port_up(self): self._register_ml2_agents() with self.subnet(network=self._network) as subnet: host_arg = {portbindings.HOST_ID: HOST} with self.port(subnet=subnet, device_owner=DEVICE_OWNER_COMPUTE, arg_list=(portbindings.HOST_ID,), **host_arg): with self.port(subnet=subnet, device_owner=DEVICE_OWNER_COMPUTE, arg_list=(portbindings.HOST_ID,), **host_arg) as port: p1 = port['port'] device = 'tap' + p1['id'] self.callbacks.update_device_up(self.adminContext, agent_id=HOST, device=device) self._delete('ports', port['port']['id']) p1_ips = [p['ip_address'] for p in p1['fixed_ips']] expected = {p1['network_id']: {'ports': {'20.0.0.1': [constants.FLOODING_ENTRY, l2pop_rpc.PortInfo( p1['mac_address'], p1_ips[0])]}, 'network_type': 'vxlan', 'segment_id': 1}} self.mock_fanout.assert_any_call( mock.ANY, 'remove_fdb_entries', expected)
def _get_port_fdb_entries(self, port): # the port might be concurrently deleted if not port or not port.get('fixed_ips'): return [] return [l2pop_rpc.PortInfo(mac_address=port['mac_address'], ip_address=ip['ip_address']) for ip in port['fixed_ips']]
def _fixed_ips_changed(self, context, orig, port, diff_ips): segment = context.bottom_bound_segment if not segment: LOG.warning(("No segment for port {} diff {}").format( context.current, diff_ips)) return orig_ips, port_ips = diff_ips if (port['device_owner'] == const.DEVICE_OWNER_DVR_INTERFACE): agent_host = context.host else: agent_host = context.original_host if not agent_host: return agent_ip = l2pop_db.get_agent_ip_by_host( db_api.get_reader_session(), agent_host, physical_network=segment.get('physical_network')) orig_mac_ip = [ l2pop_rpc.PortInfo(mac_address=port['mac_address'], ip_address=ip) for ip in orig_ips ] port_mac_ip = [ l2pop_rpc.PortInfo(mac_address=port['mac_address'], ip_address=ip) for ip in port_ips ] upd_fdb_entries = {port['network_id']: {agent_ip: {}}} ports = upd_fdb_entries[port['network_id']][agent_ip] if orig_mac_ip: ports['before'] = orig_mac_ip if port_mac_ip: ports['after'] = port_mac_ip self.L2populationAgentNotify.update_fdb_entries( self.rpc_ctx, {'chg_ip': upd_fdb_entries}) return True
def _merge_device_results(self, results, network, inserts, removes): """Merges a set of device results to the appropriate FDB table.""" for r in results: fdb = removes if 'withdrawn' in r else inserts if network['id'] not in fdb: fdb.update(self._build_fdb_template(network)) ports = fdb[network['id']]['ports'] if r['gateway_ip'] not in ports: ports[r['gateway_ip']] = set() info = l2pop_rpc.PortInfo(r['mac_address'], r['ip_address']) ports[r['gateway_ip']].add(info)
def _unmarshall_fdb_entries(fdb_entries): """Prepares fdb_entries from JSON. All methods in this class that receive messages should call this to unmarshall fdb_entries from the wire. :param fdb_entries: Original fdb_entries data-structure. Looks like: { <uuid>: { ..., 'ports': { <ip address>: [ [<mac>, <ip>], ... ], ... Or in the case of an update: { 'chg_ip': { '<uuid>': { '<agent1-IP>': { 'before': [ [<mac>, <ip>], ... ], 'after' : [ [<mac>, <ip>], ... ], }, '<agent2-IP>': { 'before': ... :returns: Deep copy with [<mac>, <ip>] converted to PortInfo """ unmarshalled = dict(fdb_entries) chg_ip_nets = [ net.values() for net in unmarshalled.get('chg_ip', {}).values() ] for agent in itertools.chain.from_iterable(chg_ip_nets): for when in ('before', 'after'): if when in agent: agent[when] = [ l2pop_rpc.PortInfo(*pi) for pi in agent[when] ] for value in unmarshalled.values(): if 'ports' in value: value['ports'] = dict( (address, [l2pop_rpc.PortInfo(*pi) for pi in port_infos]) for address, port_infos in value['ports'].items()) return unmarshalled
def test_update_port_down(self): self._register_ml2_agents() with self.subnet(network=self._network) as subnet: host_arg = {portbindings.HOST_ID: HOST} with self.port(subnet=subnet, device_owner=DEVICE_OWNER_COMPUTE, arg_list=(portbindings.HOST_ID, ), **host_arg) as port1: with self.port(subnet=subnet, device_owner=DEVICE_OWNER_COMPUTE, arg_list=(portbindings.HOST_ID, ), **host_arg) as port2: p2 = port2['port'] device2 = 'tap' + p2['id'] self.mock_fanout.reset_mock() self.callbacks.update_device_up(self.adminContext, agent_id=HOST, device=device2) p1 = port1['port'] device1 = 'tap' + p1['id'] self.callbacks.update_device_up(self.adminContext, agent_id=HOST, device=device1) self.mock_fanout.reset_mock() self.callbacks.update_device_down(self.adminContext, agent_id=HOST, device=device2) p2_ips = [p['ip_address'] for p in p2['fixed_ips']] expected = { p2['network_id']: { 'ports': { '20.0.0.1': [ l2pop_rpc.PortInfo(p2['mac_address'], p2_ips[0]) ] }, 'network_type': 'vxlan', 'segment_id': 1 } } self.mock_fanout.assert_called_with( mock.ANY, 'remove_fdb_entries', expected)
def _get_network_fdb_entries(self, context, network, bgpvpn_id): """Return an L2POP compatible dict of FDB entries for one network.""" fdb_entries = self._build_fdb_template(network) ports = fdb_entries[network['id']]['ports'] # Add a device entry for each device in this bgpvpn devices = self.bgpvpn_db.get_bgpvpn_active_devices(context, bgpvpn_id) for d in devices: if d['gateway_ip'] not in ports: ports[d['gateway_ip']] = [const.FLOODING_ENTRY] info = l2pop_rpc.PortInfo(d['mac_address'], d['ip_address']) ports[d['gateway_ip']].append(info) # Add a flood entry for any VTEP instance that is not already present gateways = self.bgpvpn_db.get_bgpvpn_gateways(context, bgpvpn_id) for g in gateways: if g['ip_address'] not in ports: ports[g['ip_address']] = [const.FLOODING_ENTRY] return fdb_entries
def test_fdb_del_flows(self): self._prepare_l2_pop_ofports() fdb_entry = {self.lvms[1].net: {'network_type': self.tunnel_type, 'segment_id': 'tun2', 'ports': {self.lvms[1].ip: [l2pop_rpc.PortInfo('mac', 'ip'), FLOODING_ENTRY]}}} with contextlib.nested( mock.patch.object(self.agent.int_br, 'install_tunnel_output'), mock.patch.object(self.agent.int_br, 'delete_tunnel_output'), ) as (install_fn, delete_fn): self.agent.fdb_remove(None, fdb_entry) install_fn.assert_called_once_with(10, 12, 22, 1, set([self.lvms[0].ip]), goto_next=True) delete_fn.assert_called_once_with(7, 12, eth_dst='mac')
def _test_host_changed(self, twice): self._register_ml2_agents() with self.subnet(network=self._network) as subnet: host_arg = {portbindings.HOST_ID: HOST} with self.port(subnet=subnet, cidr='10.0.0.0/24', device_owner=DEVICE_OWNER_COMPUTE, arg_list=(portbindings.HOST_ID, ), **host_arg) as port1: tunnel_ip = '20.0.0.1' p1 = port1['port'] device1 = 'tap' + p1['id'] self.callbacks.update_device_up(self.adminContext, agent_id=HOST, device=device1) if twice: tunnel_ip = '20.0.0.4' self._update_and_check_portbinding(p1['id'], HOST_4) self.callbacks.update_device_up(self.adminContext, agent_id=HOST_4, device=device1) self.mock_fanout.reset_mock() self._update_and_check_portbinding(p1['id'], HOST_2) p1_ips = [p['ip_address'] for p in p1['fixed_ips']] expected = { p1['network_id']: { 'ports': { tunnel_ip: [ constants.FLOODING_ENTRY, l2pop_rpc.PortInfo(p1['mac_address'], p1_ips[0]) ] }, 'network_type': 'vxlan', 'segment_id': 1 } } self.mock_fanout.assert_called_with(mock.ANY, 'remove_fdb_entries', expected)
def test_fdb_ignore_self(self): self._prepare_l2_pop_ofports() self.agent.local_ip = 'agent_ip' fdb_entry = {self.lvms[1].net: {'network_type': self.tunnel_type, 'segment_id': 'tun2', 'ports': {'agent_ip': [l2pop_rpc.PortInfo('mac', 'ip'), FLOODING_ENTRY]}}} with mock.patch.object(self.agent.ryuapp, "add_arp_table_entry") as add_fn,\ mock.patch.object(self.agent.ryuapp, "del_arp_table_entry") as del_fn: self.agent.fdb_add(None, copy.deepcopy(fdb_entry)) add_fn.assert_called_once_with(12, 'ip', 'mac') self.assertFalse(del_fn.called) self.agent.fdb_remove(None, fdb_entry) add_fn.assert_called_once_with(12, 'ip', 'mac') del_fn.assert_called_once_with(12, 'ip')
def _unmarshall_fdb_entries(fdb_entries): """Prepares fdb_entries from JSON. All methods in this class that receive messages should call this to unmarshall fdb_entries from the wire. :param fdb_entries: Original fdb_entries data-structure. Looks like: { <uuid>: { ..., 'ports': { <ip address>: [ [<mac>, <ip>], ... ], ... :returns: Deep copy with [<mac>, <ip>] converted to PortInfo """ unmarshalled = dict(fdb_entries) for value in unmarshalled.values(): if 'ports' in value: value['ports'] = dict( (address, [l2pop_rpc.PortInfo(*pi) for pi in port_infos]) for address, port_infos in value['ports'].items()) return unmarshalled
def test_portinfo_marshalled_as_list(self): entry = ['fa:16:3e:ff:8c:0f', '10.0.0.6'] payload = {'netuuid': {'ports': {'1': [l2pop_rpc.PortInfo(*entry)]}}} result = jsonutils.loads(jsonutils.dumps(payload)) self.assertEqual(entry, result['netuuid']['ports']['1'][0])
def _get_port_fdb_entries(self, port): return [ l2pop_rpc.PortInfo(mac_address=port['mac_address'], ip_address=ip['ip_address']) for ip in port['fixed_ips'] ]
def setUp(self): super(TestL2populationRpcCallBackTunnelMixinBase, self).setUp() self.vlan_manager = self.useFixture( test_vlanmanager.LocalVlanManagerFixture()).manager self.fakeagent = FakeNeutronAgent() self.fakebr = mock.Mock() Port = collections.namedtuple('Port', 'ip, ofport') LVM = collections.namedtuple( 'LVM', 'net, vlan, phys, segid, mac, ip, vif, port') self.local_ip = '127.0.0.1' self.type_gre = 'gre' self.ports = [ Port(ip='10.1.0.1', ofport='ofport1'), Port(ip='10.1.0.2', ofport='ofport2'), Port(ip='10.1.0.3', ofport='ofport3') ] self.ofports = { self.type_gre: { self.ports[0].ip: self.ports[0].ofport, self.ports[1].ip: self.ports[1].ofport, self.ports[2].ip: self.ports[2].ofport, } } self.lvms = [ LVM(net='net1', vlan=1, phys='phys1', segid='tun1', mac='mac1', ip='1.1.1.1', vif='vifid1', port='port1'), LVM(net='net2', vlan=2, phys='phys2', segid='tun2', mac='mac2', ip='2.2.2.2', vif='vifid2', port='port2'), LVM(net='net3', vlan=3, phys='phys3', segid='tun3', mac='mac3', ip='3.3.3.3', vif='vifid3', port='port3') ] self.agent_ports = { self.ports[0].ip: [(self.lvms[0].mac, self.lvms[0].ip)], self.ports[1].ip: [(self.lvms[1].mac, self.lvms[1].ip)], self.ports[2].ip: [(self.lvms[2].mac, self.lvms[2].ip)], } self.fdb_entries1 = { self.lvms[0].net: { 'network_type': self.type_gre, 'segment_id': self.lvms[0].segid, 'ports': { self.local_ip: [], self.ports[0].ip: [(self.lvms[0].mac, self.lvms[0].ip)] }, }, self.lvms[1].net: { 'network_type': self.type_gre, 'segment_id': self.lvms[1].segid, 'ports': { self.local_ip: [], self.ports[1].ip: [(self.lvms[1].mac, self.lvms[1].ip)] }, }, self.lvms[2].net: { 'network_type': self.type_gre, 'segment_id': self.lvms[2].segid, 'ports': { self.local_ip: [], self.ports[2].ip: [(self.lvms[2].mac, self.lvms[2].ip)] }, }, } for i in range(3): self.vlan_manager.add(self.lvms[i].net, self.lvms[i].vlan, self.type_gre, self.lvms[i].phys, self.lvms[i].segid, {self.lvms[i].vif: self.lvms[i].port}) setattr(self, 'lvm%d' % i, self.vlan_manager.get(self.lvms[i].net)) self.upd_fdb_entry1_val = { self.lvms[0].net: { self.ports[0].ip: { 'before': [l2pop_rpc.PortInfo(self.lvms[0].mac, self.lvms[0].ip)], 'after': [l2pop_rpc.PortInfo(self.lvms[1].mac, self.lvms[1].ip)], }, self.ports[1].ip: { 'before': [l2pop_rpc.PortInfo(self.lvms[0].mac, self.lvms[0].ip)], 'after': [l2pop_rpc.PortInfo(self.lvms[1].mac, self.lvms[1].ip)], }, }, self.lvms[1].net: { self.ports[2].ip: { 'before': [l2pop_rpc.PortInfo(self.lvms[0].mac, self.lvms[0].ip)], 'after': [l2pop_rpc.PortInfo(self.lvms[2].mac, self.lvms[2].ip)], }, }, } self.upd_fdb_entry1 = {'chg_ip': self.upd_fdb_entry1_val}
import contextlib import copy import mock import netaddr from oslo.config import cfg from oslo.utils import importutils import testtools from neutron.common import constants as n_const from neutron.plugins.common import constants as p_const from neutron.plugins.ml2.drivers.l2pop import rpc as l2pop_rpc from neutron.tests.unit.ofagent import ofa_test_base NOTIFIER = ('neutron.plugins.ml2.rpc.AgentNotifierApi') FLOODING_ENTRY = l2pop_rpc.PortInfo(*n_const.FLOODING_ENTRY) def _mock_port(is_neutron=True, normalized_name=None): p = mock.Mock() p.is_neutron_port.return_value = is_neutron if normalized_name: p.normalized_port_name.return_value = normalized_name return p class CreateAgentConfigMap(ofa_test_base.OFAAgentTestBase): def test_create_agent_config_map_succeeds(self): self.assertTrue(self.mod_agent.create_agent_config_map(cfg.CONF)) def test_create_agent_config_map_fails_for_invalid_tunnel_config(self):