NSXv: LBaaSv2 shared pools

Support shared pool fuctionality of LBaaSv2 for NSXv driver.

Change-Id: If3368b341658fe0f6073d19e6d2ca2eadb2222d3
This commit is contained in:
Kobi Samoray 2016-08-16 16:44:00 +03:00
parent af8cd3f2ca
commit 4383b9d391
10 changed files with 133 additions and 95 deletions

View File

@ -1 +1 @@
dbe29d208ac6
d49ac91b560e

View File

@ -0,0 +1,45 @@
# Copyright 2016 VMware, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
"""Support shared pools with NSXv LBaaSv2 driver
Revision ID: d49ac91b560e
Revises: dbe29d208ac6
Create Date: 2016-07-21 05:03:35.369938
"""
# revision identifiers, used by Alembic.
revision = 'd49ac91b560e'
down_revision = 'dbe29d208ac6'
from alembic import op
from sqlalchemy.engine import reflection
def upgrade():
change_pk_constraint('nsxv_lbaas_pool_bindings', ['loadbalancer_id',
'pool_id'])
change_pk_constraint('nsxv_lbaas_monitor_bindings', ['loadbalancer_id',
'pool_id',
'hm_id',
'edge_id'])
def change_pk_constraint(table_name, columns):
inspector = reflection.Inspector.from_engine(op.get_bind())
pk_constraint = inspector.get_pk_constraint(table_name)
op.drop_constraint(pk_constraint, table_name, type_='primary')
op.drop_column(table_name, 'listener_id')
op.create_primary_key(None, table_name, columns)

View File

@ -677,44 +677,38 @@ def del_nsxv_lbaas_listener_binding(session, loadbalancer_id, listener_id):
listener_id=listener_id).delete())
def add_nsxv_lbaas_pool_binding(session, loadbalancer_id, listener_id,
pool_id, edge_pool_id):
def add_nsxv_lbaas_pool_binding(session, loadbalancer_id, pool_id,
edge_pool_id):
with session.begin(subtransactions=True):
binding = nsxv_models.NsxvLbaasPoolBinding(
loadbalancer_id=loadbalancer_id,
listener_id=listener_id,
pool_id=pool_id,
edge_pool_id=edge_pool_id)
session.add(binding)
return binding
def get_nsxv_lbaas_pool_binding(session, loadbalancer_id, listener_id,
pool_id):
def get_nsxv_lbaas_pool_binding(session, loadbalancer_id, pool_id):
try:
return session.query(
nsxv_models.NsxvLbaasPoolBinding).filter_by(
loadbalancer_id=loadbalancer_id,
listener_id=listener_id,
pool_id=pool_id).one()
except exc.NoResultFound:
return
def del_nsxv_lbaas_pool_binding(session, loadbalancer_id, listener_id,
pool_id):
def del_nsxv_lbaas_pool_binding(session, loadbalancer_id, pool_id):
return (session.query(nsxv_models.NsxvLbaasPoolBinding).
filter_by(loadbalancer_id=loadbalancer_id,
listener_id=listener_id,
pool_id=pool_id).delete())
def add_nsxv_lbaas_monitor_binding(session, loadbalancer_id, listener_id,
pool_id, hm_id, edge_id, edge_mon_id):
def add_nsxv_lbaas_monitor_binding(session, loadbalancer_id, pool_id, hm_id,
edge_id, edge_mon_id):
with session.begin(subtransactions=True):
binding = nsxv_models.NsxvLbaasMonitorBinding(
loadbalancer_id=loadbalancer_id,
listener_id=listener_id,
pool_id=pool_id,
hm_id=hm_id,
edge_id=edge_id,
@ -723,13 +717,12 @@ def add_nsxv_lbaas_monitor_binding(session, loadbalancer_id, listener_id,
return binding
def get_nsxv_lbaas_monitor_binding(session, loadbalancer_id, listener_id,
pool_id, hm_id, edge_id):
def get_nsxv_lbaas_monitor_binding(session, loadbalancer_id, pool_id, hm_id,
edge_id):
try:
return session.query(
nsxv_models.NsxvLbaasMonitorBinding).filter_by(
loadbalancer_id=loadbalancer_id,
listener_id=listener_id,
pool_id=pool_id,
hm_id=hm_id,
edge_id=edge_id).one()
@ -737,11 +730,10 @@ def get_nsxv_lbaas_monitor_binding(session, loadbalancer_id, listener_id,
return
def del_nsxv_lbaas_monitor_binding(session, loadbalancer_id, listener_id,
pool_id, hm_id, edge_id):
def del_nsxv_lbaas_monitor_binding(session, loadbalancer_id, pool_id, hm_id,
edge_id):
return (session.query(nsxv_models.NsxvLbaasMonitorBinding).
filter_by(loadbalancer_id=loadbalancer_id,
listener_id=listener_id,
pool_id=pool_id,
hm_id=hm_id,
edge_id=edge_id).delete())

View File

@ -298,7 +298,6 @@ class NsxvLbaasPoolBinding(model_base.BASEV2, models.TimestampMixin):
__tablename__ = 'nsxv_lbaas_pool_bindings'
loadbalancer_id = sa.Column(sa.String(36), primary_key=True)
listener_id = sa.Column(sa.String(36), primary_key=True)
pool_id = sa.Column(sa.String(36),
sa.ForeignKey('lbaas_pools.id',
name='fk_lbaas_pools_id',
@ -313,7 +312,6 @@ class NsxvLbaasMonitorBinding(model_base.BASEV2, models.TimestampMixin):
__tablename__ = 'nsxv_lbaas_monitor_bindings'
loadbalancer_id = sa.Column(sa.String(36), primary_key=True)
listener_id = sa.Column(sa.String(36), primary_key=True)
pool_id = sa.Column(sa.String(36), primary_key=True)
hm_id = sa.Column(sa.String(36),
sa.ForeignKey('lbaas_healthmonitors.id',

View File

@ -55,18 +55,17 @@ class EdgeHealthMonitorManager(base_mgr.EdgeLoadbalancerBaseManager):
@log_helpers.log_method_call
def create(self, context, hm):
listener = hm.pool.listener
lb_id = listener.loadbalancer_id
lb_id = hm.pool.loadbalancer_id
lb_binding = nsxv_db.get_nsxv_lbaas_loadbalancer_binding(
context.session, lb_id)
pool_binding = nsxv_db.get_nsxv_lbaas_pool_binding(
context.session, lb_id, listener.id, hm.pool.id)
context.session, lb_id, hm.pool.id)
edge_id = lb_binding['edge_id']
edge_pool_id = pool_binding['edge_pool_id']
hm_binding = nsxv_db.get_nsxv_lbaas_monitor_binding(
context.session, lb_id, listener.id, hm.pool.id, hm.id, edge_id)
context.session, lb_id, hm.pool.id, hm.id, edge_id)
edge_mon_id = None
if hm_binding:
@ -80,8 +79,8 @@ class EdgeHealthMonitorManager(base_mgr.EdgeLoadbalancerBaseManager):
edge_mon_id = lb_common.extract_resource_id(h['location'])
nsxv_db.add_nsxv_lbaas_monitor_binding(
context.session, lb_id, listener.id, hm.pool.id, hm.id,
edge_id, edge_mon_id)
context.session, lb_id, hm.pool.id, hm.id, edge_id,
edge_mon_id)
except nsxv_exc.VcnsApiException:
with excutils.save_and_reraise_exception():
@ -112,16 +111,14 @@ class EdgeHealthMonitorManager(base_mgr.EdgeLoadbalancerBaseManager):
@log_helpers.log_method_call
def update(self, context, old_hm, new_hm):
listener = new_hm.pool.listener
lb_id = listener.loadbalancer_id
lb_id = new_hm.pool.loadbalancer_id
lb_binding = nsxv_db.get_nsxv_lbaas_loadbalancer_binding(
context.session, lb_id)
edge_id = lb_binding['edge_id']
hm_binding = nsxv_db.get_nsxv_lbaas_monitor_binding(
context.session, lb_id, listener.id, new_hm.pool.id, new_hm.id,
edge_id)
context.session, lb_id, new_hm.pool.id, new_hm.id, edge_id)
edge_monitor = self._convert_lbaas_monitor(new_hm)
@ -142,18 +139,17 @@ class EdgeHealthMonitorManager(base_mgr.EdgeLoadbalancerBaseManager):
@log_helpers.log_method_call
def delete(self, context, hm):
listener = hm.pool.listener
lb_id = listener.loadbalancer_id
lb_id = hm.pool.loadbalancer_id
lb_binding = nsxv_db.get_nsxv_lbaas_loadbalancer_binding(
context.session, lb_id)
pool_binding = nsxv_db.get_nsxv_lbaas_pool_binding(
context.session, lb_id, listener.id, hm.pool.id)
context.session, lb_id, hm.pool.id)
edge_id = lb_binding['edge_id']
edge_pool_id = pool_binding['edge_pool_id']
hm_binding = nsxv_db.get_nsxv_lbaas_monitor_binding(
context.session, lb_id, listener.id, hm.pool.id, hm.id, edge_id)
context.session, lb_id, hm.pool.id, hm.id, edge_id)
edge_pool = self.vcns.get_pool(edge_id, edge_pool_id)[1]
edge_pool['monitorId'].remove(hm_binding['edge_mon_id'])
@ -182,6 +178,6 @@ class EdgeHealthMonitorManager(base_mgr.EdgeLoadbalancerBaseManager):
_LE('Failed to delete monitor on edge: %s'), edge_id)
nsxv_db.del_nsxv_lbaas_monitor_binding(
context.session, lb_id, listener.id, hm.pool.id, hm.id, edge_id)
context.session, lb_id, hm.pool.id, hm.id, edge_id)
self.lbv2_driver.health_monitor.successful_completion(
context, hm, delete=True)

View File

@ -50,21 +50,21 @@ def listener_to_edge_app_profile(listener, edge_cert_id):
edge_app_profile['sslPassthrough'] = True
if listener.default_pool:
persistence = None
if listener.pool.sessionpersistence:
if listener.default_pool.sessionpersistence:
persistence = {
'method':
lb_const.SESSION_PERSISTENCE_METHOD_MAP.get(
listener.pool.sessionpersistence.type)}
listener.default_pool.sessionpersistence.type)}
if (listener.pool.sessionpersistence.type in
if (listener.default_pool.sessionpersistence.type in
lb_const.SESSION_PERSISTENCE_COOKIE_MAP):
persistence.update({
'cookieName': getattr(listener.pool.sessionpersistence,
'cookieName': getattr(
listener.default_pool.sessionpersistence,
'cookie_name',
'default_cookie_name'),
'cookieMode': lb_const.SESSION_PERSISTENCE_COOKIE_MAP[
listener.pool.sessionpersistence.type]})
listener.default_pool.sessionpersistence.type]})
edge_app_profile['persistence'] = persistence
@ -127,7 +127,7 @@ class EdgeListenerManager(base_mgr.EdgeLoadbalancerBaseManager):
if listener.default_pool and listener.default_pool.id:
pool_binding = nsxv_db.get_nsxv_lbaas_pool_binding(
context.session, lb_id, listener.id, listener.default_pool.id)
context.session, lb_id, listener.default_pool.id)
if pool_binding:
default_pool = pool_binding['edge_pool_id']
@ -183,9 +183,13 @@ class EdgeListenerManager(base_mgr.EdgeLoadbalancerBaseManager):
default_pool = None
if new_listener.default_pool and new_listener.default_pool.id:
pool_binding = nsxv_db.get_nsxv_lbaas_pool_binding(
context.session, new_listener.default_pool.id, None, None)
context.session, new_listener.loadbalancer_id,
new_listener.default_pool.id)
if pool_binding:
default_pool = pool_binding['edge_pool_id']
else:
LOG.error(_LE("Couldn't find pool binding for pool %s"),
new_listener.default_pool.id)
lb_id = new_listener.loadbalancer_id
listener_binding = nsxv_db.get_nsxv_lbaas_listener_binding(

View File

@ -53,7 +53,7 @@ class EdgeMemberManager(base_mgr.EdgeLoadbalancerBaseManager):
lb_binding = nsxv_db.get_nsxv_lbaas_loadbalancer_binding(
context.session, lb_id)
pool_binding = nsxv_db.get_nsxv_lbaas_pool_binding(
context.session, lb_id, listener.id, member.pool_id)
context.session, lb_id, member.pool_id)
edge_id = lb_binding['edge_id']
edge_pool_id = pool_binding['edge_pool_id']
@ -98,7 +98,7 @@ class EdgeMemberManager(base_mgr.EdgeLoadbalancerBaseManager):
lb_binding = nsxv_db.get_nsxv_lbaas_loadbalancer_binding(
context.session, lb_id)
pool_binding = nsxv_db.get_nsxv_lbaas_pool_binding(context.session,
lb_id, listener.id,
lb_id,
new_member.pool_id)
edge_id = lb_binding['edge_id']
@ -147,7 +147,7 @@ class EdgeMemberManager(base_mgr.EdgeLoadbalancerBaseManager):
lb_binding = nsxv_db.get_nsxv_lbaas_loadbalancer_binding(
context.session, lb_id)
pool_binding = nsxv_db.get_nsxv_lbaas_pool_binding(
context.session, lb_id, listener.id, member.pool_id)
context.session, lb_id, member.pool_id)
edge_id = lb_binding['edge_id']
edge_pool_id = pool_binding['edge_pool_id']

View File

@ -45,12 +45,9 @@ class EdgePoolManager(base_mgr.EdgeLoadbalancerBaseManager):
'transparent': False
}
listener = pool.listener
lb_id = listener.loadbalancer_id
lb_id = pool.loadbalancer_id
lb_binding = nsxv_db.get_nsxv_lbaas_loadbalancer_binding(
context.session, lb_id)
listener_binding = nsxv_db.get_nsxv_lbaas_listener_binding(
context.session, lb_id, listener.id)
edge_id = lb_binding['edge_id']
@ -59,18 +56,21 @@ class EdgePoolManager(base_mgr.EdgeLoadbalancerBaseManager):
h = self.vcns.create_pool(edge_id, edge_pool)[0]
edge_pool_id = lb_common.extract_resource_id(h['location'])
nsxv_db.add_nsxv_lbaas_pool_binding(context.session, lb_id,
listener.id,
pool.id,
edge_pool_id)
if pool.listener:
listener_binding = nsxv_db.get_nsxv_lbaas_listener_binding(
context.session, lb_id, pool.listener.id)
# Associate listener with pool
vse = listener_mgr.listener_to_edge_vse(
listener,
pool.listener,
lb_binding['vip_address'],
edge_pool_id,
listener_binding['app_profile_id'])
with locking.LockManager.get_lock(edge_id):
self.vcns.update_vip(edge_id, listener_binding['vse_id'], vse)
self.vcns.update_vip(edge_id, listener_binding['vse_id'],
vse)
self.lbv2_driver.pool.successful_completion(context, pool)
@ -90,12 +90,16 @@ class EdgePoolManager(base_mgr.EdgeLoadbalancerBaseManager):
'transparent': False
}
if new_pool.listener:
listener = new_pool.listener
lb_id = listener.loadbalancer_id
else:
lb_id = new_pool.loadbalancer_id
lb_binding = nsxv_db.get_nsxv_lbaas_loadbalancer_binding(
context.session, lb_id)
pool_binding = nsxv_db.get_nsxv_lbaas_pool_binding(
context.session, lb_id, listener.id, new_pool.id)
context.session, lb_id, new_pool.id)
edge_id = lb_binding['edge_id']
edge_pool_id = pool_binding['edge_pool_id']
@ -113,31 +117,34 @@ class EdgePoolManager(base_mgr.EdgeLoadbalancerBaseManager):
@log_helpers.log_method_call
def delete(self, context, pool):
listener = pool.listener
lb_id = listener.loadbalancer_id
lb_id = pool.loadbalancer_id
lb_binding = nsxv_db.get_nsxv_lbaas_loadbalancer_binding(
context.session, lb_id)
pool_binding = nsxv_db.get_nsxv_lbaas_pool_binding(
context.session, lb_id, listener.id, pool.id)
listener_binding = nsxv_db.get_nsxv_lbaas_listener_binding(
context.session, lb_id, listener.id)
context.session, lb_id, pool.id)
edge_id = lb_binding['edge_id']
edge_pool_id = pool_binding['edge_pool_id']
try:
if pool.listeners:
for listener in pool.listeners:
listener_binding = nsxv_db.get_nsxv_lbaas_listener_binding(
context.session, lb_id, listener.id)
vse = listener_mgr.listener_to_edge_vse(
listener,
lb_binding['vip_address'],
None,
listener_binding['app_profile_id'])
with locking.LockManager.get_lock(edge_id):
self.vcns.update_vip(edge_id, listener_binding['vse_id'], vse)
self.vcns.update_vip(
edge_id, listener_binding['vse_id'], vse)
self.vcns.delete_pool(edge_id, edge_pool_id)
self.lbv2_driver.pool.successful_completion(
context, pool, delete=True)
nsxv_db.del_nsxv_lbaas_pool_binding(
context.session, lb_id, listener.id, pool.id)
context.session, lb_id, pool.id)
except nsxv_exc.VcnsApiException:
self.lbv2_driver.pool.failed_completion(context, pool)
LOG.error(_LE('Failed to delete pool %s'), pool['id'])

View File

@ -195,7 +195,6 @@ def _create_v2_nsx_mappings(v1_pool_id, v1_hm_id, v2_pool_id, v2_lb_id,
nsxv_db.add_nsxv_lbaas_monitor_binding(
neutron_db.context.session,
v2_lb_id,
v2_listener_id,
v2_pool_id,
v2_hm_id,
v1_hm_map['edge_id'],
@ -209,7 +208,6 @@ def _create_v2_nsx_mappings(v1_pool_id, v1_hm_id, v2_pool_id, v2_lb_id,
nsxv_db.add_nsxv_lbaas_pool_binding(
neutron_db.context.session,
v2_lb_id,
v2_listener_id,
v2_pool_id,
v1_pool_map['edge_pool_id'])

View File

@ -53,7 +53,6 @@ EDGE_POOL_ID = 'pool-xx'
EDGE_POOL_DEF = {'transparent': False, 'name': 'pool_' + POOL_ID,
'algorithm': 'round-robin', 'description': ''}
POOL_BINDING = {'loadbalancer_id': LB_ID,
'listener_id': LISTENER_ID,
'pool_id': POOL_ID,
'edge_pool_id': EDGE_POOL_ID}
MEMBER_ID = 'mmm-mmm'
@ -68,7 +67,6 @@ EDGE_HM_DEF = {'maxRetries': 1, 'interval': 3, 'type': 'icmp', 'name': HM_ID,
'timeout': 3}
HM_BINDING = {'loadbalancer_id': LB_ID,
'listener_id': LISTENER_ID,
'pool_id': POOL_ID,
'hm_id': HM_ID,
'edge_id': LB_EDGE_ID,
@ -101,7 +99,9 @@ class BaseTestEdgeLbaasV2(base.BaseTestCase):
loadbalancer=self.lb)
self.pool = lb_models.Pool(POOL_ID, LB_TENANT_ID, 'pool-name', '',
None, 'HTTP', 'ROUND_ROBIN',
listener=self.listener)
loadbalancer_id=LB_ID,
listener=self.listener,
listeners=[self.listener])
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,
@ -340,8 +340,7 @@ class TestEdgeLbaasV2Pool(BaseTestEdgeLbaasV2):
mock_create_pool.assert_called_with(LB_EDGE_ID,
EDGE_POOL_DEF.copy())
mock_add_binding.assert_called_with(self.context.session,
LB_ID, LISTENER_ID, POOL_ID,
EDGE_POOL_ID)
LB_ID, POOL_ID, EDGE_POOL_ID)
edge_vip_def = EDGE_VIP_DEF.copy()
edge_vip_def['defaultPoolId'] = EDGE_POOL_ID
mock_upd_vip.assert_called_with(LB_EDGE_ID, EDGE_VIP_ID,
@ -398,7 +397,7 @@ class TestEdgeLbaasV2Pool(BaseTestEdgeLbaasV2):
EDGE_VIP_DEF)
mock_del_pool.assert_called_with(LB_EDGE_ID, EDGE_POOL_ID)
mock_del_binding.assert_called_with(
self.context.session, LB_ID, LISTENER_ID, POOL_ID)
self.context.session, LB_ID, POOL_ID)
mock_successful_completion = (
self.lbv2_driver.pool.successful_completion)
mock_successful_completion.assert_called_with(self.context,
@ -541,8 +540,8 @@ class TestEdgeLbaasV2HealthMonitor(BaseTestEdgeLbaasV2):
mock_create_hm.assert_called_with(LB_EDGE_ID, EDGE_HM_DEF)
mock_add_hm_binding.assert_called_with(
self.context.session, LB_ID, LISTENER_ID, POOL_ID, HM_ID,
LB_EDGE_ID, EDGE_HM_ID)
self.context.session, LB_ID, POOL_ID, HM_ID, LB_EDGE_ID,
EDGE_HM_ID)
edge_pool_def = EDGE_POOL_DEF.copy()
edge_pool_def['monitorId'] = [EDGE_HM_ID]
mock_update_pool.assert_called_with(
@ -610,8 +609,7 @@ class TestEdgeLbaasV2HealthMonitor(BaseTestEdgeLbaasV2):
mock_update_pool.assert_called_with(
LB_EDGE_ID, EDGE_POOL_ID, edge_pool_def)
mock_del_binding.assert_called_with(self.context.session, LB_ID,
LISTENER_ID, POOL_ID, HM_ID,
LB_EDGE_ID)
POOL_ID, HM_ID, LB_EDGE_ID)
mock_successful_completion = (
self.lbv2_driver.health_monitor.successful_completion)
mock_successful_completion.assert_called_with(self.context,