NSX-V3: Fix QoS delete

In commit I1f863bf91f712d4b12db753b13cc6b842b6918a4 the qos driver stopped
using the message queue.
So the delete callback is now called in the plugin context, after the qos
policy is already deleted.
This means that we cannot access the backend profile id in the DB, since it
was already deleted too.

Since we cannot change the DB model for Ocata, this fix looks up the profile
in the nsx backend before deleting it.

Change-Id: If038e3af16598ba17f5cf29083e15059c94e95d9
This commit is contained in:
Adit Sarfaty 2017-03-15 14:52:06 +02:00
parent bfa48c002b
commit 635833ded4
2 changed files with 35 additions and 6 deletions

View File

@ -115,10 +115,32 @@ class QosNotificationsHandler(object):
policy_id, policy_id,
profile_id) profile_id)
def _find_policy_profile_id(self, policy_id):
# Note: In Ocata the policy was already deleted from the DB and from
# the mapping table, so as a temporary fix we have to search the
# backend profiles by the id.
# In Pike the DM model will be different so the mapping entry will not
# be deleted.
all_profiles = self._nsxlib_qos.list()['results']
for profile in all_profiles:
# look only at qos profiles
if profile.get('resource_type') == 'QosSwitchingProfile':
tags = profile.get('tags', [])
for tag in tags:
if (tag.get('scope') == 'os-neutron-qos-id' and
tag.get('tag') == policy_id):
return profile.get('id')
def delete_policy(self, context, policy_id): def delete_policy(self, context, policy_id):
profile_id = nsx_db.get_switch_profile_by_qos_policy( try:
context.session, policy_id) profile_id = self._find_policy_profile_id(policy_id)
self._nsxlib_qos.delete(profile_id) if profile_id:
self._nsxlib_qos.delete(profile_id)
else:
LOG.warning(_LW("QOS delete_policy failed: Policy %w was not "
"found on backend"), policy_id)
except Exception as e:
LOG.warning(_LW("QOS delete_policy failed: %s"), e)
def update_policy(self, context, policy_id, policy): def update_policy(self, context, policy_id, policy):
profile_id = nsx_db.get_switch_profile_by_qos_policy( profile_id = nsx_db.get_switch_profile_by_qos_policy(

View File

@ -316,12 +316,19 @@ class TestQosNsxV3Notification(base.BaseQosTestCase,
qos_marking='trusted' qos_marking='trusted'
) )
@mock.patch('neutron.objects.db.api.get_object', return_value=None) def test_policy_delete_profile(self):
def test_policy_delete_profile(self, *mocks):
# test the switch profile deletion when a QoS policy is deleted # test the switch profile deletion when a QoS policy is deleted
backend_profile = {
'id': self.fake_profile_id,
'resource_type': 'QosSwitchingProfile',
'tags': [{'scope': 'os-neutron-qos-id', 'tag': self.policy.id}]}
with mock.patch( with mock.patch(
'vmware_nsxlib.v3.NsxLibQosSwitchingProfile.delete', 'vmware_nsxlib.v3.NsxLibQosSwitchingProfile.delete',
return_value=self.fake_profile return_value=self.fake_profile
) as delete_profile: ) as delete_profile,\
mock.patch(
'vmware_nsxlib.v3.NsxLibQosSwitchingProfile.list',
return_value={'results': [backend_profile]}
):
self.qos_plugin.delete_policy(self.ctxt, self.policy.id) self.qos_plugin.delete_policy(self.ctxt, self.policy.id)
delete_profile.assert_called_once_with(self.fake_profile_id) delete_profile.assert_called_once_with(self.fake_profile_id)