From 4c49c9c3906b8a0827c4adec6af21de81ae48739 Mon Sep 17 00:00:00 2001 From: Adit Sarfaty Date: Sun, 21 May 2017 16:37:01 +0300 Subject: [PATCH] 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 --- .../services/lbaas/nsx_v/v2/listener_mgr.py | 32 ++++++++++++------- .../services/lbaas/nsx_v/v2/pool_mgr.py | 29 +++++++++++++++++ 2 files changed, 49 insertions(+), 12 deletions(-) diff --git a/vmware_nsx/services/lbaas/nsx_v/v2/listener_mgr.py b/vmware_nsx/services/lbaas/nsx_v/v2/listener_mgr.py index f25ae368d1..fdcf7604ea 100644 --- a/vmware_nsx/services/lbaas/nsx_v/v2/listener_mgr.py +++ b/vmware_nsx/services/lbaas/nsx_v/v2/listener_mgr.py @@ -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, diff --git a/vmware_nsx/services/lbaas/nsx_v/v2/pool_mgr.py b/vmware_nsx/services/lbaas/nsx_v/v2/pool_mgr.py index 0cef20289f..581e731abe 100644 --- a/vmware_nsx/services/lbaas/nsx_v/v2/pool_mgr.py +++ b/vmware_nsx/services/lbaas/nsx_v/v2/pool_mgr.py @@ -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)