Fix session re-establish failure with PBM APIs

PBM APIs break the API contract in vSphere 6.5 by raising
NotAuthenticated fault instead of SecurityError when session
is expired. We do catch NotAuthenticated faults (raised by
VIM APIs), but PBM APIs use the 'vim25' namespace which
result in not identifying the session expiry case. Therefore,
the session is not re-established. Fixing it by matching the
fault name suffix with 'NotAuthenticated' in the suds WebFault
exception handler

Closes-bug: #1769755
Change-Id: I35d48c12a5b1d5fe94a10b56b1ab06c34446de28
This commit is contained in:
Vipin Balachandran 2018-05-07 14:42:49 -07:00
parent a7bbe9c847
commit d249fe1156
2 changed files with 15 additions and 7 deletions

View File

@ -380,7 +380,12 @@ class Service(object):
if detail: if detail:
for fault in detail.getChildren(): for fault in detail.getChildren():
fault_type = fault.get('type') fault_type = fault.get('type')
if fault_type.endswith(exceptions.SECURITY_ERROR): # NOTE(vbala): PBM faults use vim25 namespace. Also,
# PBM APIs throw NotAuthenticated in vSphere 6.5 for
# session expiry.
if (fault_type.endswith(exceptions.SECURITY_ERROR) or
fault_type.endswith(
exceptions.NOT_AUTHENTICATED)):
fault_type = exceptions.NOT_AUTHENTICATED fault_type = exceptions.NOT_AUTHENTICATED
fault_list.append(fault_type) fault_list.append(fault_type)
for child in fault.getChildren(): for child in fault.getChildren():

View File

@ -15,13 +15,13 @@
import io import io
import ddt
import mock import mock
import requests import requests
import six import six
import six.moves.http_client as httplib import six.moves.http_client as httplib
import suds import suds
import ddt
from oslo_vmware import exceptions from oslo_vmware import exceptions
from oslo_vmware import service from oslo_vmware import service
from oslo_vmware.tests import base from oslo_vmware.tests import base
@ -56,6 +56,7 @@ class ServiceMessagePluginTest(base.TestCase):
self.plugin.add_attribute_for_value) self.plugin.add_attribute_for_value)
@ddt.ddt
class ServiceTest(base.TestCase): class ServiceTest(base.TestCase):
def setUp(self): def setUp(self):
@ -209,8 +210,9 @@ class ServiceTest(base.TestCase):
mock.call('/Envelope/Body/Fault/detail')] mock.call('/Envelope/Body/Fault/detail')]
self.assertEqual(exp_calls, doc.childAtPath.call_args_list) self.assertEqual(exp_calls, doc.childAtPath.call_args_list)
def test_request_handler_with_security_error(self): @ddt.data('vim25:SecurityError', 'vim25:NotAuthenticated')
managed_object = 'VirtualMachine' def test_request_handler_with_pbm_session_error(self, fault_name):
managed_object = 'ProfileManager'
doc = mock.Mock() doc = mock.Mock()
def side_effect(mo, **kwargs): def side_effect(mo, **kwargs):
@ -222,7 +224,7 @@ class ServiceTest(base.TestCase):
fault_children.name = "name" fault_children.name = "name"
fault_children.getText.return_value = "value" fault_children.getText.return_value = "value"
child = mock.Mock() child = mock.Mock()
child.get.return_value = 'vim25:SecurityError' child.get.return_value = fault_name
child.getChildren.return_value = [fault_children] child.getChildren.return_value = [fault_children]
detail = mock.Mock() detail = mock.Mock()
detail.getChildren.return_value = [child] detail.getChildren.return_value = [child]
@ -231,9 +233,10 @@ class ServiceTest(base.TestCase):
svc_obj = service.Service() svc_obj = service.Service()
service_mock = svc_obj.client.service service_mock = svc_obj.client.service
setattr(service_mock, 'powerOn', side_effect) setattr(service_mock, 'get_profile_id_by_name', side_effect)
ex = self.assertRaises(exceptions.VimFaultException, svc_obj.powerOn, ex = self.assertRaises(exceptions.VimFaultException,
svc_obj.get_profile_id_by_name,
managed_object) managed_object)
self.assertEqual([exceptions.NOT_AUTHENTICATED], ex.fault_list) self.assertEqual([exceptions.NOT_AUTHENTICATED], ex.fault_list)