Enable SVI networks with hosts running opflex agent
- Allow port binding on SVI networks with hosts running opflex agent - Supported with vlan type networks (not opflex networks) - Provides a flag indicating SVI network, the vlan id and the epg is set to a unique id (SVI network id) in response to get_gbp_details. This enables the opflex agent on the host to set up the data path appropriately. Change-Id: Ia0a3e4354141b04693fda8c1079acbbc76f371d9
This commit is contained in:
parent
496f54b84a
commit
5aee410131
@ -2736,7 +2736,8 @@ class ApicMechanismDriver(api_plus.MechanismDriver,
|
|||||||
|
|
||||||
def _opflex_bind_port(self, context, segment, agent):
|
def _opflex_bind_port(self, context, segment, agent):
|
||||||
network_type = segment[api.NETWORK_TYPE]
|
network_type = segment[api.NETWORK_TYPE]
|
||||||
if self._is_opflex_type(network_type):
|
if (self._is_opflex_type(network_type) or
|
||||||
|
network_type == n_constants.TYPE_VLAN):
|
||||||
opflex_mappings = agent['configurations'].get('opflex_networks')
|
opflex_mappings = agent['configurations'].get('opflex_networks')
|
||||||
LOG.debug("Checking segment: %(segment)s "
|
LOG.debug("Checking segment: %(segment)s "
|
||||||
"for physical network: %(mappings)s ",
|
"for physical network: %(mappings)s ",
|
||||||
|
@ -72,6 +72,7 @@ EndpointPortInfo = namedtuple(
|
|||||||
'nested_domain_infra_vlan',
|
'nested_domain_infra_vlan',
|
||||||
'nested_domain_service_vlan',
|
'nested_domain_service_vlan',
|
||||||
'nested_domain_node_network_vlan',
|
'nested_domain_node_network_vlan',
|
||||||
|
'svi',
|
||||||
'epg_name',
|
'epg_name',
|
||||||
'epg_app_profile_name',
|
'epg_app_profile_name',
|
||||||
'epg_tenant_name',
|
'epg_tenant_name',
|
||||||
@ -96,7 +97,8 @@ EndpointBindingInfo = namedtuple(
|
|||||||
['host',
|
['host',
|
||||||
'level',
|
'level',
|
||||||
'network_type',
|
'network_type',
|
||||||
'physical_network'])
|
'physical_network',
|
||||||
|
'segmentation_id'])
|
||||||
|
|
||||||
EndpointSecurityGroupInfo = namedtuple(
|
EndpointSecurityGroupInfo = namedtuple(
|
||||||
'EndpointSecurityGroupInfo',
|
'EndpointSecurityGroupInfo',
|
||||||
@ -485,6 +487,7 @@ class ApicRpcHandlerMixin(object):
|
|||||||
extension_db.NetworkExtensionDb.nested_domain_service_vlan,
|
extension_db.NetworkExtensionDb.nested_domain_service_vlan,
|
||||||
extension_db.NetworkExtensionDb.
|
extension_db.NetworkExtensionDb.
|
||||||
nested_domain_node_network_vlan,
|
nested_domain_node_network_vlan,
|
||||||
|
extension_db.NetworkExtensionDb.svi,
|
||||||
db.NetworkMapping.epg_name,
|
db.NetworkMapping.epg_name,
|
||||||
db.NetworkMapping.epg_app_profile_name,
|
db.NetworkMapping.epg_app_profile_name,
|
||||||
db.NetworkMapping.epg_tenant_name,
|
db.NetworkMapping.epg_tenant_name,
|
||||||
@ -575,6 +578,7 @@ class ApicRpcHandlerMixin(object):
|
|||||||
ml2_models.PortBindingLevel.level,
|
ml2_models.PortBindingLevel.level,
|
||||||
segment_models.NetworkSegment.network_type,
|
segment_models.NetworkSegment.network_type,
|
||||||
segment_models.NetworkSegment.physical_network,
|
segment_models.NetworkSegment.physical_network,
|
||||||
|
segment_models.NetworkSegment.segmentation_id,
|
||||||
))
|
))
|
||||||
query += lambda q: q.join(
|
query += lambda q: q.join(
|
||||||
segment_models.NetworkSegment,
|
segment_models.NetworkSegment,
|
||||||
@ -862,6 +866,7 @@ class ApicRpcHandlerMixin(object):
|
|||||||
details['network_id'] = port_info.network_id
|
details['network_id'] = port_info.network_id
|
||||||
details['network_type'] = binding_info[-1].network_type
|
details['network_type'] = binding_info[-1].network_type
|
||||||
details['physical_network'] = binding_info[-1].physical_network
|
details['physical_network'] = binding_info[-1].physical_network
|
||||||
|
details['segmentation_id'] = binding_info[-1].segmentation_id
|
||||||
details['port_id'] = port_info.port_id
|
details['port_id'] = port_info.port_id
|
||||||
|
|
||||||
return details
|
return details
|
||||||
@ -896,6 +901,10 @@ class ApicRpcHandlerMixin(object):
|
|||||||
details['dns_domain'] = port_info.net_dns_domain or ''
|
details['dns_domain'] = port_info.net_dns_domain or ''
|
||||||
details['enable_dhcp_optimization'] = self.enable_dhcp_opt
|
details['enable_dhcp_optimization'] = self.enable_dhcp_opt
|
||||||
details['enable_metadata_optimization'] = self.enable_metadata_opt
|
details['enable_metadata_optimization'] = self.enable_metadata_opt
|
||||||
|
if port_info.svi:
|
||||||
|
details['endpoint_group_name'] = port_info.network_id
|
||||||
|
details['svi'] = True
|
||||||
|
else:
|
||||||
details['endpoint_group_name'] = port_info.epg_name
|
details['endpoint_group_name'] = port_info.epg_name
|
||||||
details['floating_ip'] = self._build_fips(info)
|
details['floating_ip'] = self._build_fips(info)
|
||||||
details['host'] = port_info.host
|
details['host'] = port_info.host
|
||||||
|
@ -342,7 +342,8 @@ class ApicAimTestCase(test_address_scope.AddressScopeTestCase,
|
|||||||
'apic:nat_type', SNAT_POOL,
|
'apic:nat_type', SNAT_POOL,
|
||||||
ACTIVE_ACTIVE_AAP,
|
ACTIVE_ACTIVE_AAP,
|
||||||
CIDR, PROV, CONS, SVI,
|
CIDR, PROV, CONS, SVI,
|
||||||
BGP, BGP_TYPE, ASN
|
BGP, BGP_TYPE, ASN,
|
||||||
|
'provider:network_type'
|
||||||
)
|
)
|
||||||
self.name_mapper = apic_mapper.APICNameMapper()
|
self.name_mapper = apic_mapper.APICNameMapper()
|
||||||
self.t1_aname = self.name_mapper.project(None, 't1')
|
self.t1_aname = self.name_mapper.project(None, 't1')
|
||||||
@ -4723,6 +4724,28 @@ class TestPortBinding(ApicAimTestCase):
|
|||||||
self.assertEqual({'port_filter': False, 'ovs_hybrid_plug': False},
|
self.assertEqual({'port_filter': False, 'ovs_hybrid_plug': False},
|
||||||
port['binding:vif_details'])
|
port['binding:vif_details'])
|
||||||
|
|
||||||
|
def test_bind_opflex_agent_svi(self):
|
||||||
|
self._register_agent('host1', AGENT_CONF_OPFLEX)
|
||||||
|
aim_ctx = aim_context.AimContext(self.db_session)
|
||||||
|
hlink_1 = aim_infra.HostLink(
|
||||||
|
host_name='host1',
|
||||||
|
interface_name='eth1',
|
||||||
|
path='topology/pod-1/paths-102/pathep-[eth1/8]')
|
||||||
|
self.aim_mgr.create(aim_ctx, hlink_1)
|
||||||
|
|
||||||
|
net = self._make_network(self.fmt, 'net1', True,
|
||||||
|
arg_list=self.extension_attributes,
|
||||||
|
**{'apic:svi': 'True', 'provider:network_type': u'vlan'})
|
||||||
|
|
||||||
|
self._make_subnet(self.fmt, net, '10.0.1.1', '10.0.1.0/24')
|
||||||
|
port = self._make_port(self.fmt, net['network']['id'])['port']
|
||||||
|
port_id = port['id']
|
||||||
|
port = self._bind_port_to_host(port_id, 'host1')['port']
|
||||||
|
|
||||||
|
self.assertEqual('ovs', port['binding:vif_type'])
|
||||||
|
self.assertEqual({'port_filter': False, 'ovs_hybrid_plug': False},
|
||||||
|
port['binding:vif_details'])
|
||||||
|
|
||||||
def test_bind_opflex_agent_with_firewall_enabled(self):
|
def test_bind_opflex_agent_with_firewall_enabled(self):
|
||||||
self.driver.enable_iptables_firewall = True
|
self.driver.enable_iptables_firewall = True
|
||||||
self._register_agent('host1', AGENT_CONF_OPFLEX)
|
self._register_agent('host1', AGENT_CONF_OPFLEX)
|
||||||
@ -9193,6 +9216,42 @@ class TestOpflexRpc(ApicAimTestCase):
|
|||||||
def test_endpoint_details_bound_active_active_aap(self):
|
def test_endpoint_details_bound_active_active_aap(self):
|
||||||
self._test_endpoint_details_bound(active_active_aap=True)
|
self._test_endpoint_details_bound(active_active_aap=True)
|
||||||
|
|
||||||
|
def test_endpoint_details_bound_svi(self):
|
||||||
|
self._register_agent('h1', AGENT_CONF_OPFLEX)
|
||||||
|
|
||||||
|
aim_ctx = aim_context.AimContext(self.db_session)
|
||||||
|
hlink_1 = aim_infra.HostLink(
|
||||||
|
host_name='h1',
|
||||||
|
interface_name='eth1',
|
||||||
|
path='topology/pod-1/paths-102/pathep-[eth1/8]')
|
||||||
|
self.aim_mgr.create(aim_ctx, hlink_1)
|
||||||
|
|
||||||
|
network = self._make_network(self.fmt, 'net1', True,
|
||||||
|
arg_list=self.extension_attributes,
|
||||||
|
**{'apic:svi': 'True',
|
||||||
|
'provider:network_type': u'vlan'})
|
||||||
|
net1 = network['network']
|
||||||
|
gw1_ip = '10.0.1.1'
|
||||||
|
self._make_subnet(self.fmt, network, gw1_ip, cidr='10.0.1.0/24')
|
||||||
|
|
||||||
|
# Make a VM port.
|
||||||
|
p1 = self._make_port(self.fmt, net1['id'],
|
||||||
|
device_owner='compute:')['port']
|
||||||
|
self._bind_port_to_host(p1['id'], 'h1')
|
||||||
|
|
||||||
|
request = {
|
||||||
|
'device': 'tap' + p1['id'],
|
||||||
|
'timestamp': 12345,
|
||||||
|
'request_id': 'a_request'
|
||||||
|
}
|
||||||
|
response = self.driver.request_endpoint_details(
|
||||||
|
n_context.get_admin_context(), request=request, host='h1')
|
||||||
|
gbp_details = response['gbp_details']
|
||||||
|
self.assertEqual(True, gbp_details.get('svi'))
|
||||||
|
neutron_details = response['neutron_details']
|
||||||
|
self.assertEqual(net1['provider:segmentation_id'],
|
||||||
|
neutron_details.get('segmentation_id'))
|
||||||
|
|
||||||
def test_endpoint_details_unbound(self):
|
def test_endpoint_details_unbound(self):
|
||||||
host = 'host1'
|
host = 'host1'
|
||||||
net = self._make_network(self.fmt, 'net1', True)
|
net = self._make_network(self.fmt, 'net1', True)
|
||||||
|
Loading…
Reference in New Issue
Block a user