NSX|v: Fix LBaaS session persistence

Session persistense of the pool should be configured in the relevant
listener backend application profile.
This should happen both when the user configures the pool before the listener,
and when the user configured the listener first.
It should also be updated/deleted if the pool definition is changed.

Change-Id: I727c83056af861bdd18e7e4bcc2929c47ae78293
This commit is contained in:
Adit Sarfaty 2017-05-21 16:37:01 +03:00
parent 026450a64e
commit 4c49c9c390
2 changed files with 49 additions and 12 deletions

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:
if listener.default_pool.sessionpersistence:
if listener.default_pool.session_persistence:
persistence = {
'method':
lb_const.SESSION_PERSISTENCE_METHOD_MAP.get(
listener.default_pool.sessionpersistence.type)}
listener.default_pool.session_persistence.type)}
if (listener.default_pool.sessionpersistence.type in
if (listener.default_pool.session_persistence.type in
lb_const.SESSION_PERSISTENCE_COOKIE_MAP):
persistence.update({
'cookieName': getattr(
listener.default_pool.sessionpersistence,
listener.default_pool.session_persistence,
'cookie_name',
'default_cookie_name'),
'cookieMode': lb_const.SESSION_PERSISTENCE_COOKIE_MAP[
listener.default_pool.sessionpersistence.type]})
listener.default_pool.session_persistence.type]})
edge_app_profile['persistence'] = persistence
@ -103,6 +103,18 @@ def listener_to_edge_vse(context, listener, vip_address, default_pool,
return vse
def update_app_profile(vcns, context, listener, edge_id, edge_cert_id=None):
lb_id = listener.loadbalancer_id
listener_binding = nsxv_db.get_nsxv_lbaas_listener_binding(
context.session, lb_id, listener.id)
app_profile_id = listener_binding['app_profile_id']
app_profile = listener_to_edge_app_profile(listener, edge_cert_id)
with locking.LockManager.get_lock(edge_id):
vcns.update_app_profile(
edge_id, app_profile_id, app_profile)
return app_profile_id
class EdgeListenerManager(base_mgr.EdgeLoadbalancerBaseManager):
@log_helpers.log_method_call
def __init__(self, vcns_driver):
@ -233,14 +245,10 @@ class EdgeListenerManager(base_mgr.EdgeLoadbalancerBaseManager):
edge_id)
edge_cert_id = cert_binding['edge_cert_id']
app_profile_id = listener_binding['app_profile_id']
app_profile = listener_to_edge_app_profile(new_listener, edge_cert_id)
try:
with locking.LockManager.get_lock(edge_id):
self.vcns.update_app_profile(
edge_id, app_profile_id, app_profile)
app_profile_id = update_app_profile(
self.vcns, context, new_listener,
edge_id, edge_cert_id=edge_cert_id)
vse = listener_to_edge_vse(context, new_listener,
lb_binding['vip_address'],
default_pool,

View File

@ -76,6 +76,11 @@ class EdgePoolManager(base_mgr.EdgeLoadbalancerBaseManager):
with locking.LockManager.get_lock(edge_id):
self.vcns.update_vip(edge_id, listener_binding['vse_id'],
vse)
# This action also set this pool as the default pool of the
# listener, so the application profile may need to be updated
if pool.session_persistence:
listener_mgr.update_app_profile(
self.vcns, context, pool.listener, edge_id)
self.lbv2_driver.pool.successful_completion(context, pool)
@ -115,6 +120,16 @@ class EdgePoolManager(base_mgr.EdgeLoadbalancerBaseManager):
self.lbv2_driver.pool.successful_completion(context, new_pool)
# if the the session_persistence was changed,
# we may need to update the listener application profile
if new_pool.listener:
old_sess_persist = old_pool.session_persistence
new_sess_persist = new_pool.session_persistence
if new_sess_persist != old_sess_persist:
listener_mgr.update_app_profile(
self.vcns, context, new_pool.listener, edge_id)
except nsxv_exc.VcnsApiException:
with excutils.save_and_reraise_exception():
self.lbv2_driver.pool.failed_completion(context, new_pool)
@ -132,9 +147,16 @@ class EdgePoolManager(base_mgr.EdgeLoadbalancerBaseManager):
edge_id = lb_binding['edge_id']
edge_pool_id = pool_binding['edge_pool_id']
listeners_to_update = []
try:
if pool.listeners:
for listener in pool.listeners:
# the pool session persistence may affect the associated
# pool application profile
if (pool.session_persistence and listener.default_pool and
listener.default_pool.id == pool.id):
listeners_to_update.append(listener)
listener_binding = nsxv_db.get_nsxv_lbaas_listener_binding(
context.session, lb_id, listener.id)
vse = listener_mgr.listener_to_edge_vse(
@ -151,6 +173,13 @@ class EdgePoolManager(base_mgr.EdgeLoadbalancerBaseManager):
context, pool, delete=True)
nsxv_db.del_nsxv_lbaas_pool_binding(
context.session, lb_id, pool.id)
for listener in listeners_to_update:
# need to update the listeners too, now with no default pool
listener.default_pool = None
listener_mgr.update_app_profile(
self.vcns, context, listener, edge_id)
except nsxv_exc.VcnsApiException:
self.lbv2_driver.pool.failed_completion(context, pool)
LOG.error('Failed to delete pool %s', pool.id)