commit d9f49736e6a40452e8e9db0f39f1239f1d7e2d59 Author: Kobi Samoray Date: Tue Oct 13 20:29:55 2020 +0300 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 diff --git a/vmware_nsx/services/lbaas/octavia/octavia_driver.py b/vmware_nsx/services/lbaas/octavia/octavia_driver.py index 3200fd8..99c356a 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 b58ef68..a55b3d3 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):