From 0d13668f139b1e0198f2396d026b05f772580c00 Mon Sep 17 00:00:00 2001 From: Kobi Samoray Date: Tue, 13 Oct 2020 20:29:55 +0300 Subject: [PATCH] Octavia driver bug fixes - Octavia removes the HM while a pool is deleted. Driver should remove the HM too, or otherwise it'll remain dangling. - When member is deleted, NSXV checks if the member subnet interface should be removed from the LB, which requires the id property to be set in the member list. Yet this property was missing. Change-Id: Id7b9cc5c51829c0b3a205decfb3f2733d1a57034 --- .../services/lbaas/octavia/octavia_driver.py | 8 +++++ .../lbaas/octavia/octavia_listener.py | 33 +++++++++++++++++-- 2 files changed, 39 insertions(+), 2 deletions(-) diff --git a/vmware_nsx/services/lbaas/octavia/octavia_driver.py b/vmware_nsx/services/lbaas/octavia/octavia_driver.py index e6264d94c9..45d1deef46 100644 --- a/vmware_nsx/services/lbaas/octavia/octavia_driver.py +++ b/vmware_nsx/services/lbaas/octavia/octavia_driver.py @@ -190,6 +190,8 @@ class NSXOctaviaDriver(driver_base.ProviderDriver): if project_id is None: project_id = parent_project_id pool_dict['tenant_id'] = pool_dict['project_id'] = project_id + for member in pool_dict.get('members', []): + member['id'] = member['member_id'] return pool_dict @@ -303,9 +305,15 @@ class NSXOctaviaDriver(driver_base.ProviderDriver): elif obj_type == 'Pool': if 'listener' not in obj_dict: self._get_listener_in_pool_dict(obj_dict, is_update) + if obj_dict.get('loadbalancer_id'): + # Generate a loadbalancer object + obj_dict['loadbalancer'] = self._get_load_balancer_dict( + obj_dict['loadbalancer_id']) if obj_dict.get('healthmonitor'): obj_dict['healthmonitor']['id'] = obj_dict[ 'healthmonitor']['healthmonitor_id'] + for member in obj_dict.get('members', []): + member['id'] = member['member_id'] elif obj_type == 'Member': # Get the pool object diff --git a/vmware_nsx/services/lbaas/octavia/octavia_listener.py b/vmware_nsx/services/lbaas/octavia/octavia_listener.py index b58ef68085..a55b3d3c58 100644 --- a/vmware_nsx/services/lbaas/octavia/octavia_listener.py +++ b/vmware_nsx/services/lbaas/octavia/octavia_listener.py @@ -350,6 +350,7 @@ class NSXOctaviaListenerEndpoint(object): member['pool'] = pool self.member.delete_cascade(ctx, member, dummy_completor) if pool.get('healthmonitor'): + pool['healthmonitor']['pool'] = pool self.healthmonitor.delete_cascade( ctx, pool['healthmonitor'], dummy_completor) self.pool.delete_cascade(ctx, pool, dummy_completor) @@ -461,16 +462,44 @@ class NSXOctaviaListenerEndpoint(object): @log_helpers.log_method_call def pool_delete(self, ctxt, pool): + delete_result = {'value': True} + + def dummy_completor(success=True): + delete_result['value'] = success + ctx = neutron_context.Context(None, pool['project_id']) + + # Octavia removes pool HMs while pool is deleted + if pool.get('healthmonitor'): + pool['healthmonitor']['pool'] = pool + try: + self.healthmonitor.delete_cascade( + ctx, pool['healthmonitor'], dummy_completor) + except Exception as e: + delete_result['value'] = False + LOG.error('NSX driver pool_delete failed to delete HM %s', e) + + for member in pool.get('members', []): + try: + if not member.get('pool'): + member['pool'] = pool + self.member.delete_cascade(ctx, member, dummy_completor) + except Exception as e: + delete_result['value'] = False + LOG.error('NSX driver pool_delete failed to delete member' + ' %s %s', member['id'], e) + completor = self.get_completor_func(constants.POOLS, pool, delete=True) try: self.pool.delete(ctx, pool, completor) except Exception as e: LOG.error('NSX driver pool_delete failed %s', e) + delete_result['value'] = False + + if not delete_result['value']: completor(success=False) - return False - return True + return delete_result['value'] @log_helpers.log_method_call def pool_update(self, ctxt, old_pool, new_pool):