Fix dynamic domain association
The current dynamic domain association fails to correctly associate and disassociate domains during port binding for external networks. Change-Id: Iecd6989b7eec691374d2258ea2f8273210eac28f
This commit is contained in:
parent
a7cf4ee4b5
commit
c2b3fbf2bd
|
@ -36,6 +36,7 @@ from neutron.db.models import segment as segments_model
|
|||
from neutron.db import models_v2
|
||||
from neutron.db import rbac_db_models
|
||||
from neutron.db import segments_db
|
||||
from neutron.extensions import external_net
|
||||
from neutron.plugins.common import constants as pconst
|
||||
from neutron.plugins.ml2 import driver_api as api
|
||||
from neutron.plugins.ml2 import models
|
||||
|
@ -420,10 +421,11 @@ class ApicMechanismDriver(api_plus.MechanismDriver,
|
|||
domain_type=utils.OPENSTACK_VMM_TYPE)
|
||||
|
||||
domains = []
|
||||
if aim_hd_mappings:
|
||||
domains = self._get_unique_domains(aim_hd_mappings)
|
||||
if not domains:
|
||||
domains, _ = self.get_aim_domains(aim_ctx)
|
||||
if not isinstance(ns, nat_strategy.NoNatStrategy):
|
||||
if aim_hd_mappings:
|
||||
domains = self._get_unique_domains(aim_hd_mappings)
|
||||
if not domains:
|
||||
domains, _ = self.get_aim_domains(aim_ctx)
|
||||
|
||||
ns.create_l3outside(aim_ctx, l3out, vmm_domains=domains)
|
||||
ns.create_external_network(aim_ctx, ext_net)
|
||||
|
@ -2874,10 +2876,24 @@ class ApicMechanismDriver(api_plus.MechanismDriver,
|
|||
port_context.bottom_bound_segment[api.NETWORK_TYPE])):
|
||||
self._associate_domain(port_context, is_vmm=True)
|
||||
|
||||
def _skip_domain_processing(self, port_context):
|
||||
ext_net = port_context.network.current
|
||||
# skip domain processing if it's not managed by us, or
|
||||
# for external networks with NAT (FIPs or SNAT),
|
||||
if not ext_net:
|
||||
return True
|
||||
if ext_net[external_net.EXTERNAL] is True:
|
||||
_, _, ns = self._get_aim_nat_strategy(ext_net)
|
||||
if not isinstance(ns, nat_strategy.NoNatStrategy):
|
||||
return True
|
||||
return False
|
||||
|
||||
def _associate_domain(self, port_context, is_vmm=True):
|
||||
port = port_context.current
|
||||
session = port_context._plugin_context.session
|
||||
aim_ctx = aim_context.AimContext(session)
|
||||
if self._skip_domain_processing(port_context):
|
||||
return
|
||||
ptg = None
|
||||
# TODO(kentwu): remove this coupling with policy driver if possible
|
||||
if self.gbp_driver:
|
||||
|
@ -2899,6 +2915,10 @@ class ApicMechanismDriver(api_plus.MechanismDriver,
|
|||
domains = []
|
||||
try:
|
||||
if is_vmm:
|
||||
# Get all the openstack VMM domains. We either
|
||||
# get domains from a lookup of the HostDomainMappingV2
|
||||
# table, or we get all the applicable VMM domains
|
||||
# found in AIM. We then apply these to the EPG.
|
||||
if aim_hd_mappings:
|
||||
domains = [{'type': mapping.domain_type,
|
||||
'name': mapping.domain_name}
|
||||
|
@ -2917,6 +2937,10 @@ class ApicMechanismDriver(api_plus.MechanismDriver,
|
|||
vmms = aim_epg.vmm_domains
|
||||
self.aim.update(aim_ctx, epg, vmm_domains=vmms)
|
||||
else:
|
||||
# Get all the Physical domains. We either get domains
|
||||
# from a lookup of the HostDomainMappingV2
|
||||
# table, or we get all the applicable Physical
|
||||
# domains found in AIM. We then apply these to the EPG.
|
||||
if aim_hd_mappings:
|
||||
domains = [{'name': mapping.domain_name}
|
||||
for mapping in aim_hd_mappings
|
||||
|
@ -2947,16 +2971,15 @@ class ApicMechanismDriver(api_plus.MechanismDriver,
|
|||
port = port_context.current
|
||||
if (self._is_opflex_type(btm[api.NETWORK_TYPE]) or
|
||||
self._is_supported_non_opflex_type(btm[api.NETWORK_TYPE])):
|
||||
if self._skip_domain_processing(port_context):
|
||||
return
|
||||
host_id = (port_context.original_host if use_original
|
||||
else port_context.host)
|
||||
session = port_context._plugin_context.session
|
||||
aim_ctx = aim_context.AimContext(session)
|
||||
aim_hd_mappings = (self.aim.find(aim_ctx,
|
||||
aim_infra.HostDomainMappingV2,
|
||||
host_name=host_id) or
|
||||
self.aim.find(aim_ctx,
|
||||
aim_infra.HostDomainMappingV2,
|
||||
host_name=DEFAULT_HOST_DOMAIN))
|
||||
aim_hd_mappings = self.aim.find(aim_ctx,
|
||||
aim_infra.HostDomainMappingV2,
|
||||
host_name=host_id)
|
||||
if not aim_hd_mappings:
|
||||
return
|
||||
|
||||
|
@ -2984,16 +3007,22 @@ class ApicMechanismDriver(api_plus.MechanismDriver,
|
|||
if self.gbp_driver:
|
||||
ptg, pt = self.gbp_driver._port_id_to_ptg(
|
||||
port_context._plugin_context, port['id'])
|
||||
|
||||
def _bound_port_query(session, port, hosts=None):
|
||||
ports = (session.query(models.PortBindingLevel).
|
||||
join(models_v2.Port, models_v2.Port.id ==
|
||||
models.PortBindingLevel.port_id))
|
||||
if hosts:
|
||||
ports = ports.filter(
|
||||
models.PortBindingLevel.host.in_(hosts))
|
||||
ports = ports.filter(
|
||||
models.PortBindingLevel.port_id != port['id'])
|
||||
return ports
|
||||
|
||||
if ptg:
|
||||
# if there are no other ports under this PTG bound to those
|
||||
# hosts under this vmm, release the domain
|
||||
bound_ports = (session
|
||||
.query(models.PortBindingLevel)
|
||||
.join(models_v2.Port,
|
||||
models_v2.Port.id ==
|
||||
models.PortBindingLevel.port_id)
|
||||
.filter(models.PortBindingLevel.host.in_(hosts))
|
||||
.filter(models.PortBindingLevel.port_id != port['id']))
|
||||
bound_ports = _bound_port_query(session, port, hosts=hosts)
|
||||
bound_ports = [x['port_id'] for x in bound_ports]
|
||||
ptg_ports = self.gbp_driver.get_ptg_port_ids(
|
||||
port_context._plugin_context, ptg)
|
||||
|
@ -3004,17 +3033,8 @@ class ApicMechanismDriver(api_plus.MechanismDriver,
|
|||
else:
|
||||
# if there are no other ports under this network bound to those
|
||||
# hosts under this vmm, release the domain
|
||||
ports = (session
|
||||
.query(models.PortBindingLevel)
|
||||
.join(models_v2.Port,
|
||||
models_v2.Port.id ==
|
||||
models.PortBindingLevel.port_id)
|
||||
.filter(models_v2.Port.network_id ==
|
||||
port['network_id'])
|
||||
.filter(models.PortBindingLevel.host.in_(hosts))
|
||||
.filter(models.PortBindingLevel.port_id != port['id'])
|
||||
.first())
|
||||
if ports:
|
||||
ports = _bound_port_query(session, port, hosts=hosts)
|
||||
if ports.first():
|
||||
return
|
||||
mapping = self._get_network_mapping(
|
||||
session, port['network_id'])
|
||||
|
|
|
@ -5150,6 +5150,8 @@ class TestExternalConnectivityBase(object):
|
|||
self._make_ext_network('net1',
|
||||
dn=self.dn_t1_l1_n1,
|
||||
cidrs=['20.10.0.0/16', '4.4.4.0/24'])
|
||||
if self.nat_type is not 'distributed' and self.nat_type is not 'edge':
|
||||
vmm_domains = []
|
||||
self.mock_ns.create_l3outside.assert_called_once_with(
|
||||
mock.ANY,
|
||||
aim_resource.L3Outside(tenant_name=self.t1_aname, name='l1'),
|
||||
|
@ -6122,10 +6124,12 @@ class TestPortOnPhysicalNode(TestPortVlanNetwork):
|
|||
self.assertEqual(set([]),
|
||||
set(self._doms(epg1.physical_domains,
|
||||
with_type=False)))
|
||||
# delete the wildcard port
|
||||
# delete the wildcard port -- the domain should still
|
||||
# be associated, since we aren't identifying all of the
|
||||
# host-specific mappings
|
||||
self._delete('ports', p3['port']['id'])
|
||||
epg1 = self.aim_mgr.get(aim_ctx, epg1)
|
||||
self.assertEqual(set([]),
|
||||
self.assertEqual(set([('vm3', 'OpenStack')]),
|
||||
set(self._doms(epg1.vmm_domains)))
|
||||
self.assertEqual(set([]),
|
||||
set(self._doms(epg1.physical_domains,
|
||||
|
@ -6135,7 +6139,7 @@ class TestPortOnPhysicalNode(TestPortVlanNetwork):
|
|||
with self.port(subnet=sub1) as p2:
|
||||
p2 = self._bind_port_to_host(p2['port']['id'], 'h1')
|
||||
epg1 = self.aim_mgr.get(aim_ctx, epg1)
|
||||
self.assertEqual(set([]),
|
||||
self.assertEqual(set([('vm3', 'OpenStack')]),
|
||||
set(self._doms(epg1.vmm_domains)))
|
||||
self.assertEqual(set(['ph1']),
|
||||
set(self._doms(epg1.physical_domains,
|
||||
|
@ -6143,7 +6147,7 @@ class TestPortOnPhysicalNode(TestPortVlanNetwork):
|
|||
# move port to another host
|
||||
p2 = self._bind_port_to_host(p2['port']['id'], 'h2')
|
||||
epg1 = self.aim_mgr.get(aim_ctx, epg1)
|
||||
self.assertEqual(set([]),
|
||||
self.assertEqual(set([('vm3', 'OpenStack')]),
|
||||
set(self._doms(epg1.vmm_domains)))
|
||||
self.assertEqual(set(['ph2']),
|
||||
set(self._doms(epg1.physical_domains,
|
||||
|
@ -6152,7 +6156,7 @@ class TestPortOnPhysicalNode(TestPortVlanNetwork):
|
|||
with self.port(subnet=sub1) as p2a:
|
||||
p2a = self._bind_port_to_host(p2a['port']['id'], 'h2a')
|
||||
epg1 = self.aim_mgr.get(aim_ctx, epg1)
|
||||
self.assertEqual(set([]),
|
||||
self.assertEqual(set([('vm3', 'OpenStack')]),
|
||||
set(self._doms(epg1.vmm_domains)))
|
||||
self.assertEqual(set(['ph2']),
|
||||
set(self._doms(epg1.physical_domains,
|
||||
|
@ -6161,7 +6165,7 @@ class TestPortOnPhysicalNode(TestPortVlanNetwork):
|
|||
# delete 1st port
|
||||
self._delete('ports', p2['port']['id'])
|
||||
epg1 = self.aim_mgr.get(aim_ctx, epg1)
|
||||
self.assertEqual(set([]),
|
||||
self.assertEqual(set([('vm3', 'OpenStack')]),
|
||||
set(self._doms(epg1.vmm_domains)))
|
||||
self.assertEqual(set(['ph2']),
|
||||
set(self._doms(epg1.physical_domains,
|
||||
|
@ -6169,7 +6173,7 @@ class TestPortOnPhysicalNode(TestPortVlanNetwork):
|
|||
# delete the last port
|
||||
self._delete('ports', p2a['port']['id'])
|
||||
epg1 = self.aim_mgr.get(aim_ctx, epg1)
|
||||
self.assertEqual(set([]),
|
||||
self.assertEqual(set([('vm3', 'OpenStack')]),
|
||||
set(self._doms(epg1.vmm_domains)))
|
||||
self.assertEqual(set([]),
|
||||
set(self._doms(epg1.physical_domains,
|
||||
|
@ -6179,17 +6183,19 @@ class TestPortOnPhysicalNode(TestPortVlanNetwork):
|
|||
with self.port(subnet=sub1) as p3:
|
||||
p3 = self._bind_port_to_host(p3['port']['id'], 'h3')
|
||||
epg1 = self.aim_mgr.get(aim_ctx, epg1)
|
||||
self.assertEqual(set([]),
|
||||
self.assertEqual(set([('vm3', 'OpenStack')]),
|
||||
set(self._doms(epg1.vmm_domains)))
|
||||
self.assertEqual(set(['ph3']),
|
||||
set(self._doms(epg1.physical_domains,
|
||||
with_type=False)))
|
||||
# delete the wildcard port
|
||||
# delete the wildcard port -- the domain should still
|
||||
# be associated, since we aren't identifying all of the
|
||||
# host-specific mappings
|
||||
self._delete('ports', p3['port']['id'])
|
||||
epg1 = self.aim_mgr.get(aim_ctx, epg1)
|
||||
self.assertEqual(set([]),
|
||||
self.assertEqual(set([('vm3', 'OpenStack')]),
|
||||
set(self._doms(epg1.vmm_domains)))
|
||||
self.assertEqual(set([]),
|
||||
self.assertEqual(set(['ph3']),
|
||||
set(self._doms(epg1.physical_domains,
|
||||
with_type=False)))
|
||||
|
||||
|
@ -6232,6 +6238,243 @@ class TestPortOnPhysicalNode(TestPortVlanNetwork):
|
|||
set(self._doms(epg1.physical_domains,
|
||||
with_type=False)))
|
||||
|
||||
def _external_net_test_setup(self, aim_ctx, domains, mappings,
|
||||
agents, nat_type=None):
|
||||
for domain in domains:
|
||||
self.aim_mgr.create(aim_ctx,
|
||||
aim_resource.VMMDomain(type=domain['type'],
|
||||
name=domain['name'],
|
||||
overwrite=True))
|
||||
for mapping in mappings:
|
||||
hd_mapping = aim_infra.HostDomainMappingV2(
|
||||
host_name=mapping['host'],
|
||||
domain_name=mapping['name'],
|
||||
domain_type=mapping['type'])
|
||||
self.aim_mgr.create(aim_ctx, hd_mapping)
|
||||
for agent in agents:
|
||||
self._register_agent(agent, AGENT_CONF_OPFLEX)
|
||||
net1 = self._make_ext_network('net1',
|
||||
dn=self.dn_t1_l1_n1,
|
||||
nat_type=nat_type)
|
||||
epg1 = self._net_2_epg(net1)
|
||||
epg1 = self.aim_mgr.get(aim_ctx, epg1)
|
||||
return net1, epg1
|
||||
|
||||
def test_no_nat_external_net_default_domains(self):
|
||||
# no-NAT external networks rely on port-binding
|
||||
# to dynamically associate domains to the external EPG
|
||||
aim_ctx = aim_context.AimContext(self.db_session)
|
||||
domains = [{'type': 'OpenStack', 'name': 'cloud-rtp-1-VMM'},
|
||||
{'type': 'OpenStack', 'name': 'vm1'}]
|
||||
mappings = []
|
||||
agents = ['opflex-1', 'opflex-2']
|
||||
net1, epg1 = self._external_net_test_setup(aim_ctx, domains,
|
||||
mappings, agents,
|
||||
nat_type='')
|
||||
|
||||
self.assertEqual(set([]),
|
||||
set(self._doms(epg1.vmm_domains)))
|
||||
self.assertEqual(set([]),
|
||||
set(self._doms(epg1.physical_domains,
|
||||
with_type=False)))
|
||||
|
||||
with self.subnet(network={'network': net1}) as sub1:
|
||||
|
||||
# "normal" port on opflex host
|
||||
with self.port(subnet=sub1) as p1:
|
||||
p1 = self._bind_port_to_host(p1['port']['id'], 'opflex-1')
|
||||
epg1 = self.aim_mgr.get(aim_ctx, epg1)
|
||||
self.assertEqual(set([('cloud-rtp-1-VMM', 'OpenStack'),
|
||||
('vm1', 'OpenStack')]),
|
||||
set(self._doms(epg1.vmm_domains)))
|
||||
self.assertEqual(set([]),
|
||||
set(self._doms(epg1.physical_domains,
|
||||
with_type=False)))
|
||||
with self.port(subnet=sub1) as p2:
|
||||
p2 = self._bind_port_to_host(p2['port']['id'], 'opflex-2')
|
||||
epg1 = self.aim_mgr.get(aim_ctx, epg1)
|
||||
self.assertEqual(set([('cloud-rtp-1-VMM', 'OpenStack'),
|
||||
('vm1', 'OpenStack')]),
|
||||
set(self._doms(epg1.vmm_domains)))
|
||||
self.assertEqual(set([]),
|
||||
set(self._doms(epg1.physical_domains,
|
||||
with_type=False)))
|
||||
# unbind the port - should still have both, since
|
||||
# we don't know that we can delete the wildcard entry
|
||||
p2 = self._bind_port_to_host(p2['port']['id'], None)
|
||||
epg1 = self.aim_mgr.get(aim_ctx, epg1)
|
||||
self.assertEqual(set([('cloud-rtp-1-VMM', 'OpenStack'),
|
||||
('vm1', 'OpenStack')]),
|
||||
set(self._doms(epg1.vmm_domains)))
|
||||
self.assertEqual(set([]),
|
||||
set(self._doms(epg1.physical_domains,
|
||||
with_type=False)))
|
||||
p2 = self._bind_port_to_host(p2['port']['id'], 'opflex-2')
|
||||
p1 = self._bind_port_to_host(p1['port']['id'], None)
|
||||
epg1 = self.aim_mgr.get(aim_ctx, epg1)
|
||||
self.assertEqual(set([('cloud-rtp-1-VMM', 'OpenStack'),
|
||||
('vm1', 'OpenStack')]),
|
||||
set(self._doms(epg1.vmm_domains)))
|
||||
self.assertEqual(set([]),
|
||||
set(self._doms(epg1.physical_domains,
|
||||
with_type=False)))
|
||||
# unbind port 1 -- domains left in place, as all default
|
||||
# domain cases should leave domains associated (to keep
|
||||
# backwards compatibility).
|
||||
p2 = self._bind_port_to_host(p2['port']['id'], None)
|
||||
epg1 = self.aim_mgr.get(aim_ctx, epg1)
|
||||
self.assertEqual(set([('cloud-rtp-1-VMM', 'OpenStack'),
|
||||
('vm1', 'OpenStack')]),
|
||||
set(self._doms(epg1.vmm_domains)))
|
||||
self.assertEqual(set([]),
|
||||
set(self._doms(epg1.physical_domains,
|
||||
with_type=False)))
|
||||
|
||||
def test_no_nat_external_net_specific_domains(self):
|
||||
# no-NAT external networks rely on port-binding
|
||||
# to dynamically associate domains to the external EPG
|
||||
aim_ctx = aim_context.AimContext(self.db_session)
|
||||
domains = [{'type': 'OpenStack', 'name': 'cloud-rtp-1-VMM'},
|
||||
{'type': 'OpenStack', 'name': 'vm1'}]
|
||||
mappings = [{'type': 'OpenStack',
|
||||
'host': '*',
|
||||
'name': 'cloud-rtp-1-VMM'},
|
||||
{'type': 'OpenStack',
|
||||
'host': 'opflex-1',
|
||||
'name': 'vm1'}]
|
||||
agents = ['opflex-1', 'opflex-2']
|
||||
net1, epg1 = self._external_net_test_setup(aim_ctx, domains,
|
||||
mappings, agents,
|
||||
nat_type='')
|
||||
|
||||
self.assertEqual(set([]),
|
||||
set(self._doms(epg1.vmm_domains)))
|
||||
self.assertEqual(set([]),
|
||||
set(self._doms(epg1.physical_domains,
|
||||
with_type=False)))
|
||||
|
||||
with self.subnet(network={'network': net1}) as sub1:
|
||||
|
||||
# "normal" port on opflex host
|
||||
with self.port(subnet=sub1) as p1:
|
||||
p1 = self._bind_port_to_host(p1['port']['id'], 'opflex-1')
|
||||
epg1 = self.aim_mgr.get(aim_ctx, epg1)
|
||||
self.assertEqual(set([('vm1', 'OpenStack')]),
|
||||
set(self._doms(epg1.vmm_domains)))
|
||||
self.assertEqual(set([]),
|
||||
set(self._doms(epg1.physical_domains,
|
||||
with_type=False)))
|
||||
with self.port(subnet=sub1) as p2:
|
||||
p2 = self._bind_port_to_host(p2['port']['id'], 'opflex-2')
|
||||
epg1 = self.aim_mgr.get(aim_ctx, epg1)
|
||||
self.assertEqual(set([('cloud-rtp-1-VMM', 'OpenStack'),
|
||||
('vm1', 'OpenStack')]),
|
||||
set(self._doms(epg1.vmm_domains)))
|
||||
self.assertEqual(set([]),
|
||||
set(self._doms(epg1.physical_domains,
|
||||
with_type=False)))
|
||||
# unbind the port - should still have both, since
|
||||
# we don't know that we can delete the wildcard entry
|
||||
p2 = self._bind_port_to_host(p2['port']['id'], None)
|
||||
epg1 = self.aim_mgr.get(aim_ctx, epg1)
|
||||
self.assertEqual(set([('cloud-rtp-1-VMM', 'OpenStack'),
|
||||
('vm1', 'OpenStack')]),
|
||||
set(self._doms(epg1.vmm_domains)))
|
||||
self.assertEqual(set([]),
|
||||
set(self._doms(epg1.physical_domains,
|
||||
with_type=False)))
|
||||
p2 = self._bind_port_to_host(p2['port']['id'], 'opflex-2')
|
||||
p1 = self._bind_port_to_host(p1['port']['id'], None)
|
||||
epg1 = self.aim_mgr.get(aim_ctx, epg1)
|
||||
self.assertEqual(set([('cloud-rtp-1-VMM', 'OpenStack')]),
|
||||
set(self._doms(epg1.vmm_domains)))
|
||||
self.assertEqual(set([]),
|
||||
set(self._doms(epg1.physical_domains,
|
||||
with_type=False)))
|
||||
# unbind port 1 -- should remove all domains, as
|
||||
# there aren't any ports left in the EPG
|
||||
p2 = self._bind_port_to_host(p2['port']['id'], None)
|
||||
epg1 = self.aim_mgr.get(aim_ctx, epg1)
|
||||
self.assertEqual(set([('cloud-rtp-1-VMM', 'OpenStack')]),
|
||||
set(self._doms(epg1.vmm_domains)))
|
||||
self.assertEqual(set([]),
|
||||
set(self._doms(epg1.physical_domains,
|
||||
with_type=False)))
|
||||
|
||||
def test_nat_external_net_specific_domains(self):
|
||||
# no-NAT external networks rely on port-binding
|
||||
# to dynamically associate domains to the external EPG
|
||||
aim_ctx = aim_context.AimContext(self.db_session)
|
||||
domains = [{'type': 'OpenStack', 'name': 'cloud-rtp-1-VMM'},
|
||||
{'type': 'OpenStack', 'name': 'vm1'}]
|
||||
mappings = [{'type': 'OpenStack',
|
||||
'host': '*',
|
||||
'name': 'cloud-rtp-1-VMM'},
|
||||
{'type': 'OpenStack',
|
||||
'host': 'opflex-1',
|
||||
'name': 'vm1'}]
|
||||
agents = ['opflex-1', 'opflex-1']
|
||||
net1, epg1 = self._external_net_test_setup(aim_ctx, domains,
|
||||
mappings, agents)
|
||||
|
||||
self.assertEqual(set([('cloud-rtp-1-VMM', 'OpenStack'),
|
||||
('vm1', 'OpenStack')]),
|
||||
set(self._doms(epg1.vmm_domains)))
|
||||
self.assertEqual(set([]),
|
||||
set(self._doms(epg1.physical_domains,
|
||||
with_type=False)))
|
||||
|
||||
with self.subnet(network={'network': net1}) as sub1:
|
||||
|
||||
# "normal" port on opflex host
|
||||
with self.port(subnet=sub1) as p1:
|
||||
p1 = self._bind_port_to_host(p1['port']['id'], 'opflex-1')
|
||||
epg1 = self.aim_mgr.get(aim_ctx, epg1)
|
||||
self.assertEqual(set([('cloud-rtp-1-VMM', 'OpenStack'),
|
||||
('vm1', 'OpenStack')]),
|
||||
set(self._doms(epg1.vmm_domains)))
|
||||
self.assertEqual(set([]),
|
||||
set(self._doms(epg1.physical_domains,
|
||||
with_type=False)))
|
||||
with self.port(subnet=sub1) as p2:
|
||||
p2 = self._bind_port_to_host(p2['port']['id'], 'opflex-2')
|
||||
epg1 = self.aim_mgr.get(aim_ctx, epg1)
|
||||
self.assertEqual(set([('cloud-rtp-1-VMM', 'OpenStack'),
|
||||
('vm1', 'OpenStack')]),
|
||||
set(self._doms(epg1.vmm_domains)))
|
||||
self.assertEqual(set([]),
|
||||
set(self._doms(epg1.physical_domains,
|
||||
with_type=False)))
|
||||
# unbind the port - should still have both, since
|
||||
# we don't know that we can delete the wildcard entry
|
||||
p2 = self._bind_port_to_host(p2['port']['id'], None)
|
||||
epg1 = self.aim_mgr.get(aim_ctx, epg1)
|
||||
self.assertEqual(set([('cloud-rtp-1-VMM', 'OpenStack'),
|
||||
('vm1', 'OpenStack')]),
|
||||
set(self._doms(epg1.vmm_domains)))
|
||||
self.assertEqual(set([]),
|
||||
set(self._doms(epg1.physical_domains,
|
||||
with_type=False)))
|
||||
p2 = self._bind_port_to_host(p2['port']['id'], 'opflex-2')
|
||||
p1 = self._bind_port_to_host(p1['port']['id'], None)
|
||||
epg1 = self.aim_mgr.get(aim_ctx, epg1)
|
||||
self.assertEqual(set([('cloud-rtp-1-VMM', 'OpenStack'),
|
||||
('vm1', 'OpenStack')]),
|
||||
set(self._doms(epg1.vmm_domains)))
|
||||
self.assertEqual(set([]),
|
||||
set(self._doms(epg1.physical_domains,
|
||||
with_type=False)))
|
||||
# unbind port 1 -- should remove all domains, as
|
||||
# there aren't any ports left in the EPG
|
||||
p2 = self._bind_port_to_host(p2['port']['id'], None)
|
||||
epg1 = self.aim_mgr.get(aim_ctx, epg1)
|
||||
self.assertEqual(set([('cloud-rtp-1-VMM', 'OpenStack'),
|
||||
('vm1', 'OpenStack')]),
|
||||
set(self._doms(epg1.vmm_domains)))
|
||||
self.assertEqual(set([]),
|
||||
set(self._doms(epg1.physical_domains,
|
||||
with_type=False)))
|
||||
|
||||
|
||||
class TestPortOnPhysicalNodeSingleDriver(TestPortOnPhysicalNode):
|
||||
# Tests for binding port on physical node where no other ML2 mechanism
|
||||
|
|
Loading…
Reference in New Issue