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:
for fault in detail.getChildren():
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_list.append(fault_type)
for child in fault.getChildren():

View File

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