Merge "Multiple host links support"
This commit is contained in:
commit
362a5977c7
|
@ -2670,17 +2670,40 @@ class ApicMechanismDriver(api_plus.MechanismDriver,
|
|||
if exist:
|
||||
return
|
||||
|
||||
static_path_updated = False
|
||||
aim_ctx = aim_context.AimContext(db_session=session)
|
||||
host_link = self.aim.find(aim_ctx, aim_infra.HostLink, host_name=host)
|
||||
if not host_link or not host_link[0].path:
|
||||
LOG.warning(_LW('No host link information found for host %s'),
|
||||
host)
|
||||
return
|
||||
host_link = host_link[0].path
|
||||
host_link_net_labels = self.aim.find(
|
||||
aim_ctx, aim_infra.HostLinkNetworkLabel, host_name=host,
|
||||
network_label=segment[api.PHYSICAL_NETWORK])
|
||||
if host_link_net_labels:
|
||||
for hl_net_label in host_link_net_labels:
|
||||
interface = hl_net_label.interface_name
|
||||
host_link = self.aim.find(
|
||||
aim_ctx, aim_infra.HostLink, host_name=host,
|
||||
interface_name=interface)
|
||||
if not host_link or not host_link[0].path:
|
||||
LOG.warning(_LW('No host link information found for host: '
|
||||
'%(host)s, interface: %(interface)s'),
|
||||
{'host': host, 'interface': interface})
|
||||
continue
|
||||
host_link = host_link[0].path
|
||||
self._update_static_path_for_network(
|
||||
session, port_context.network.current, segment,
|
||||
**{'old_path' if remove else 'new_path': host_link})
|
||||
static_path_updated = True
|
||||
|
||||
self._update_static_path_for_network(
|
||||
session, port_context.network.current, segment,
|
||||
**{'old_path' if remove else 'new_path': host_link})
|
||||
# acting as a fallback also
|
||||
if not static_path_updated:
|
||||
host_link = self.aim.find(aim_ctx, aim_infra.HostLink,
|
||||
host_name=host)
|
||||
if not host_link or not host_link[0].path:
|
||||
LOG.warning(_LW('No host link information found for host %s'),
|
||||
host)
|
||||
return
|
||||
host_link = host_link[0].path
|
||||
self._update_static_path_for_network(
|
||||
session, port_context.network.current, segment,
|
||||
**{'old_path' if remove else 'new_path': host_link})
|
||||
|
||||
def _release_dynamic_segment(self, port_context, use_original=False):
|
||||
top = (port_context.original_top_bound_segment if use_original
|
||||
|
|
|
@ -43,6 +43,7 @@ from neutron.tests.unit.extensions import test_securitygroup
|
|||
from neutron_lib import constants as n_constants
|
||||
from neutron_lib.plugins import directory
|
||||
from opflexagent import constants as ofcst
|
||||
from oslo_config import cfg
|
||||
import webob.exc
|
||||
|
||||
from gbpservice.neutron.db import implicitsubnetpool_db # noqa
|
||||
|
@ -5043,6 +5044,90 @@ class TestPortVlanNetwork(ApicAimTestCase):
|
|||
[{'path': self.hlink1.path, 'encap': 'vlan-%s' % vlan_p1}],
|
||||
epg1.static_paths)
|
||||
|
||||
def test_ports_with_2_hostlinks(self):
|
||||
aim_ctx = aim_context.AimContext(self.db_session)
|
||||
hlink_1a = aim_infra.HostLink(
|
||||
host_name='h1',
|
||||
interface_name='eth1',
|
||||
path='topology/pod-1/paths-102/pathep-[eth1/8]')
|
||||
hlink_1b = aim_infra.HostLink(
|
||||
host_name='h1',
|
||||
interface_name='eth2',
|
||||
path='topology/pod-1/paths-102/pathep-[eth1/9]')
|
||||
self.aim_mgr.create(aim_ctx, hlink_1a)
|
||||
self.aim_mgr.create(aim_ctx, hlink_1b)
|
||||
hlink_net_lable1 = aim_infra.HostLinkNetworkLabel(
|
||||
host_name='h1', network_label='physnet3',
|
||||
interface_name='eth1')
|
||||
hlink_net_lable2 = aim_infra.HostLinkNetworkLabel(
|
||||
host_name='h1', network_label='physnet3',
|
||||
interface_name='eth2')
|
||||
hlink_net_lable3 = aim_infra.HostLinkNetworkLabel(
|
||||
host_name='h1', network_label='physnet2',
|
||||
interface_name='eth999')
|
||||
self.aim_mgr.create(aim_ctx, hlink_net_lable1)
|
||||
self.aim_mgr.create(aim_ctx, hlink_net_lable2)
|
||||
self.aim_mgr.create(aim_ctx, hlink_net_lable3)
|
||||
|
||||
net_type = cfg.CONF.ml2.tenant_network_types[0]
|
||||
net1 = self._make_network(
|
||||
self.fmt, 'net1', True,
|
||||
arg_list=('provider:physical_network', 'provider:network_type'),
|
||||
**{'provider:physical_network': 'physnet3',
|
||||
'provider:network_type': net_type})['network']
|
||||
epg1 = self._net_2_epg(net1)
|
||||
|
||||
with self.subnet(network={'network': net1}) as sub1:
|
||||
with self.port(subnet=sub1) as p1:
|
||||
# bind p1 to host h1
|
||||
p1 = self._bind_port_to_host(p1['port']['id'], 'h1')
|
||||
vlan_p1 = self._check_binding(p1['port']['id'])
|
||||
|
||||
epg1 = self.aim_mgr.get(aim_ctx, epg1)
|
||||
self.assertEqual(
|
||||
[{'path': hlink_1a.path, 'encap': 'vlan-%s' % vlan_p1},
|
||||
{'path': hlink_1b.path, 'encap': 'vlan-%s' % vlan_p1}],
|
||||
epg1.static_paths)
|
||||
|
||||
# test the fallback
|
||||
net2 = self._make_network(
|
||||
self.fmt, 'net2', True,
|
||||
arg_list=('provider:physical_network', 'provider:network_type'),
|
||||
**{'provider:physical_network': 'physnet2',
|
||||
'provider:network_type': net_type})['network']
|
||||
epg2 = self._net_2_epg(net2)
|
||||
|
||||
with self.subnet(network={'network': net2}) as sub2:
|
||||
with self.port(subnet=sub2) as p2:
|
||||
# bind p2 to host h1
|
||||
p2 = self._bind_port_to_host(p2['port']['id'], 'h1')
|
||||
vlan_p2 = self._check_binding(p2['port']['id'])
|
||||
|
||||
self.assertNotEqual(vlan_p1, vlan_p2)
|
||||
|
||||
host_links = self.aim_mgr.find(aim_ctx, aim_infra.HostLink,
|
||||
host_name='h1')
|
||||
epg2 = self.aim_mgr.get(aim_ctx, epg2)
|
||||
self.assertEqual(
|
||||
[{'path': host_links[0].path, 'encap': 'vlan-%s' % vlan_p2}],
|
||||
epg2.static_paths)
|
||||
|
||||
self._delete('ports', p2['port']['id'])
|
||||
epg2 = self.aim_mgr.get(aim_ctx, epg2)
|
||||
self._check_no_dynamic_segment(net2['id'])
|
||||
self.assertEqual([], epg2.static_paths)
|
||||
|
||||
epg1 = self.aim_mgr.get(aim_ctx, epg1)
|
||||
self.assertEqual(
|
||||
[{'path': hlink_1a.path, 'encap': 'vlan-%s' % vlan_p1},
|
||||
{'path': hlink_1b.path, 'encap': 'vlan-%s' % vlan_p1}],
|
||||
epg1.static_paths)
|
||||
|
||||
self._delete('ports', p1['port']['id'])
|
||||
epg1 = self.aim_mgr.get(aim_ctx, epg1)
|
||||
self._check_no_dynamic_segment(net1['id'])
|
||||
self.assertEqual([], epg1.static_paths)
|
||||
|
||||
def test_network_on_multiple_hosts(self):
|
||||
aim_ctx = aim_context.AimContext(self.db_session)
|
||||
|
||||
|
|
Loading…
Reference in New Issue