Merge "NSXv: Connect LB interfaces to member subnets"
This commit is contained in:
commit
2ce8e5fefc
@ -33,15 +33,20 @@ def get_lb_resource_id(lb_id):
|
||||
return ('lbaas-' + lb_id)[:36]
|
||||
|
||||
|
||||
def get_lbaas_edge_id(context, plugin, lb_id, vip_addr, subnet_id, tenant_id):
|
||||
subnet = plugin.get_subnet(context, subnet_id)
|
||||
def get_lb_interface(context, plugin, lb_id, subnet_id):
|
||||
filters = {'fixed_ips': {'subnet_id': [subnet_id]},
|
||||
'device_id': [lb_id],
|
||||
'device_owner': [constants.DEVICE_OWNER_NEUTRON_PREFIX + 'LB']}
|
||||
|
||||
lb_ports = plugin.get_ports(context.elevated(), filters=filters)
|
||||
return lb_ports
|
||||
|
||||
|
||||
def create_lb_interface(context, plugin, lb_id, subnet_id, tenant_id,
|
||||
vip_addr=None, subnet=None):
|
||||
if not subnet:
|
||||
subnet = plugin.get_subnet(context, subnet_id)
|
||||
network_id = subnet.get('network_id')
|
||||
availability_zone = plugin.get_network_az(context, network_id)
|
||||
|
||||
resource_id = get_lb_resource_id(lb_id)
|
||||
|
||||
edge_id = plugin.edge_manager.allocate_lb_edge_appliance(
|
||||
context, resource_id, availability_zone=availability_zone)
|
||||
|
||||
port_dict = {'name': 'lb_if-' + lb_id,
|
||||
'admin_state_up': True,
|
||||
@ -55,18 +60,46 @@ def get_lbaas_edge_id(context, plugin, lb_id, vip_addr, subnet_id, tenant_id):
|
||||
port = plugin.base_create_port(context, {'port': port_dict})
|
||||
ip_addr = port['fixed_ips'][0]['ip_address']
|
||||
net = netaddr.IPNetwork(subnet['cidr'])
|
||||
resource_id = get_lb_resource_id(lb_id)
|
||||
|
||||
address_groups = [{'primaryAddress': ip_addr,
|
||||
'subnetPrefixLength': str(net.prefixlen),
|
||||
'subnetMask': str(net.netmask),
|
||||
'secondaryAddresses': {
|
||||
'type': 'secondary_addresses',
|
||||
'ipAddress': [vip_addr]}
|
||||
}]
|
||||
'subnetMask': str(net.netmask)}]
|
||||
|
||||
if vip_addr:
|
||||
address_groups[0]['secondaryAddresses'] = {
|
||||
'type': 'secondary_addresses', 'ipAddress': [vip_addr]}
|
||||
|
||||
edge_utils.update_internal_interface(
|
||||
plugin.nsx_v, context, resource_id,
|
||||
network_id, address_groups)
|
||||
|
||||
|
||||
def delete_lb_interface(context, plugin, lb_id, subnet_id):
|
||||
resource_id = get_lb_resource_id(lb_id)
|
||||
subnet = plugin.get_subnet(context, subnet_id)
|
||||
network_id = subnet.get('network_id')
|
||||
lb_ports = get_lb_interface(context, plugin, lb_id, subnet_id)
|
||||
for lb_port in lb_ports:
|
||||
plugin.delete_port(context, lb_port['id'])
|
||||
|
||||
edge_utils.delete_interface(plugin.nsx_v, context, resource_id, network_id,
|
||||
dist=False)
|
||||
|
||||
|
||||
def get_lbaas_edge_id(context, plugin, lb_id, vip_addr, subnet_id, tenant_id):
|
||||
subnet = plugin.get_subnet(context, subnet_id)
|
||||
network_id = subnet.get('network_id')
|
||||
availability_zone = plugin.get_network_az(context, network_id)
|
||||
|
||||
resource_id = get_lb_resource_id(lb_id)
|
||||
|
||||
edge_id = plugin.edge_manager.allocate_lb_edge_appliance(
|
||||
context, resource_id, availability_zone=availability_zone)
|
||||
|
||||
create_lb_interface(context, plugin, lb_id, subnet_id, tenant_id,
|
||||
vip_addr=vip_addr, subnet=subnet)
|
||||
|
||||
gw_ip = subnet.get('gateway_ip')
|
||||
if gw_ip:
|
||||
plugin.nsx_v.update_routes(edge_id, gw_ip, [])
|
||||
|
@ -52,6 +52,13 @@ class EdgeMemberManager(base_mgr.EdgeLoadbalancerBaseManager):
|
||||
edge_id = lb_binding['edge_id']
|
||||
edge_pool_id = pool_binding['edge_pool_id']
|
||||
with locking.LockManager.get_lock(edge_id):
|
||||
# Verify that Edge appliance is connected to the member's subnet
|
||||
if not lb_common.get_lb_interface(
|
||||
context, self.core_plugin, lb_id, member.subnet_id):
|
||||
lb_common.create_lb_interface(
|
||||
context, self.core_plugin, lb_id, member.subnet_id,
|
||||
member.tenant_id)
|
||||
|
||||
edge_pool = self.vcns.get_pool(edge_id, edge_pool_id)[1]
|
||||
edge_member = {
|
||||
'ipAddress': member.address,
|
||||
@ -137,6 +144,19 @@ class EdgeMemberManager(base_mgr.EdgeLoadbalancerBaseManager):
|
||||
edge_pool_id = pool_binding['edge_pool_id']
|
||||
|
||||
with locking.LockManager.get_lock(edge_id):
|
||||
# we should remove LB subnet interface if no members are attached
|
||||
# and this is not the LB's VIP interface
|
||||
remove_interface = True
|
||||
if member.subnet_id == member.pool.loadbalancer.vip_subnet_id:
|
||||
remove_interface = False
|
||||
else:
|
||||
for m in member.pool.members:
|
||||
if m.subnet_id == member.subnet_id and m.id != member.id:
|
||||
remove_interface = False
|
||||
if remove_interface:
|
||||
lb_common.delete_lb_interface(context, self.core_plugin, lb_id,
|
||||
member.subnet_id)
|
||||
|
||||
edge_pool = self.vcns.get_pool(edge_id, edge_pool_id)[1]
|
||||
|
||||
for i, m in enumerate(edge_pool['member']):
|
||||
|
@ -112,7 +112,8 @@ class BaseTestEdgeLbaasV2(base.BaseTestCase):
|
||||
None, 'HTTP', 'ROUND_ROBIN',
|
||||
loadbalancer_id=LB_ID,
|
||||
listener=self.listener,
|
||||
listeners=[self.listener])
|
||||
listeners=[self.listener],
|
||||
loadbalancer=self.lb)
|
||||
self.member = lb_models.Member(MEMBER_ID, LB_TENANT_ID, POOL_ID,
|
||||
MEMBER_ADDRESS, 80, 1, pool=self.pool)
|
||||
self.hm = lb_models.HealthMonitor(HM_ID, LB_TENANT_ID, 'PING', 3, 3,
|
||||
@ -510,6 +511,10 @@ class TestEdgeLbaasV2Member(BaseTestEdgeLbaasV2):
|
||||
) as mock_get_pool_binding, \
|
||||
mock.patch.object(self.edge_driver.vcns, 'get_pool'
|
||||
) as mock_get_pool, \
|
||||
mock.patch.object(self.core_plugin, 'get_ports'
|
||||
) as mock_get_ports, \
|
||||
mock.patch.object(lb_common, 'delete_lb_interface'
|
||||
) as mock_del_lb_iface, \
|
||||
mock.patch.object(self.edge_driver.vcns, 'update_pool'
|
||||
) as mock_update_pool:
|
||||
mock_get_lb_binding.return_value = LB_BINDING
|
||||
@ -517,12 +522,14 @@ class TestEdgeLbaasV2Member(BaseTestEdgeLbaasV2):
|
||||
edge_pool_def = EDGE_POOL_DEF.copy()
|
||||
edge_pool_def['member'] = [EDGE_MEMBER_DEF]
|
||||
mock_get_pool.return_value = (None, edge_pool_def)
|
||||
|
||||
mock_get_ports.return_value = []
|
||||
self.edge_driver.member.delete(self.context, self.member)
|
||||
|
||||
edge_pool_def['member'] = []
|
||||
mock_update_pool.assert_called_with(
|
||||
LB_EDGE_ID, EDGE_POOL_ID, edge_pool_def)
|
||||
mock_del_lb_iface.assert_called_with(
|
||||
self.context, self.core_plugin, LB_ID, None)
|
||||
mock_successful_completion = (
|
||||
self.lbv2_driver.member.successful_completion)
|
||||
mock_successful_completion.assert_called_with(self.context,
|
||||
|
Loading…
x
Reference in New Issue
Block a user