Re-authenticating on session invalidation
To set the ground for singleton oneview_client and re-use the session token, first, it needs to re-authenticate when the session token becomes invalid. This will ensure that a singleton instance of oneview_client won't break the service when the object is alive further than the token expiration time. Change-Id: Ia01435faf5f4bf84d896dc20ad07eed75280df3e
This commit is contained in:
		@@ -100,6 +100,26 @@ class BaseClient(object):
 | 
			
		||||
        else:
 | 
			
		||||
            return r
 | 
			
		||||
 | 
			
		||||
    def _logout(self):
 | 
			
		||||
        if self.manager_url in ("", None):
 | 
			
		||||
            raise exceptions.OneViewConnectionError(
 | 
			
		||||
                "Can't connect to OneView: 'manager_url' configuration"
 | 
			
		||||
                "parameter is blank")
 | 
			
		||||
 | 
			
		||||
        url = '%s/rest/login-sessions' % self.manager_url
 | 
			
		||||
        headers = {
 | 
			
		||||
            'X-Api-Version': str(SUPPORTED_ONEVIEW_VERSION),
 | 
			
		||||
            'Auth': self.session_id
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        verify_ssl = self._get_verify_connection_option()
 | 
			
		||||
 | 
			
		||||
        r = requests.delete(url,
 | 
			
		||||
                            headers=headers,
 | 
			
		||||
                            verify=verify_ssl)
 | 
			
		||||
        if r.status_code == 400:
 | 
			
		||||
            raise exceptions.OneViewNotAuthorizedException()
 | 
			
		||||
 | 
			
		||||
    def _get_verify_connection_option(self):
 | 
			
		||||
        verify_status = False
 | 
			
		||||
        user_cacert = self.tls_cacert_file
 | 
			
		||||
@@ -153,6 +173,11 @@ class BaseClient(object):
 | 
			
		||||
            }
 | 
			
		||||
            url = '%s%s' % (self.manager_url, uri)
 | 
			
		||||
            body = json.dumps(body)
 | 
			
		||||
            try:
 | 
			
		||||
                response = self._do_request(url, headers, body, request_type)
 | 
			
		||||
            except exceptions.OneViewNotAuthorizedException:
 | 
			
		||||
                self.session_id = self.get_session()
 | 
			
		||||
                headers['Auth'] = self.session_id
 | 
			
		||||
                response = self._do_request(url, headers, body, request_type)
 | 
			
		||||
 | 
			
		||||
            json_response = response.json()
 | 
			
		||||
@@ -708,7 +733,7 @@ def _check_request_status(response):
 | 
			
		||||
    elif status == 500:
 | 
			
		||||
        raise exceptions.OneViewInternalServerError()
 | 
			
		||||
    # Any other unexpected status are logged
 | 
			
		||||
    elif status not in (200, 202,):
 | 
			
		||||
    elif status not in (200, 202):
 | 
			
		||||
        message = (
 | 
			
		||||
            "OneView appliance returned an unknown response status: %s"
 | 
			
		||||
            % status
 | 
			
		||||
 
 | 
			
		||||
@@ -30,6 +30,69 @@ from oneview_client.tests import fixtures
 | 
			
		||||
from oneview_client import utils
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class OneViewClientAuthTestCase(unittest.TestCase):
 | 
			
		||||
 | 
			
		||||
    def setUp(self):
 | 
			
		||||
        super(OneViewClientAuthTestCase, self).setUp()
 | 
			
		||||
        self.manager_url = 'https://1.2.3.4'
 | 
			
		||||
        self.username = 'user'
 | 
			
		||||
        self.password = 'password'
 | 
			
		||||
 | 
			
		||||
    @mock.patch.object(requests, 'delete', autospec=True)
 | 
			
		||||
    @mock.patch.object(requests, 'get', autospec=True)
 | 
			
		||||
    @mock.patch.object(requests, 'post', autospec=True)
 | 
			
		||||
    def test_re_login(self,
 | 
			
		||||
                      mock_post,
 | 
			
		||||
                      mock_get,
 | 
			
		||||
                      mock_delete):
 | 
			
		||||
        oneview_client = client.ClientV2(self.manager_url,
 | 
			
		||||
                                         self.username,
 | 
			
		||||
                                         self.password)
 | 
			
		||||
        response = mock_post.return_value
 | 
			
		||||
        response.json.return_value = {'sessionID': 'aaabbb'}
 | 
			
		||||
        response.status_code = http_client.OK
 | 
			
		||||
        mock_post.return_value = response
 | 
			
		||||
 | 
			
		||||
        response1 = mock_get.return_value
 | 
			
		||||
        response1.status_code = http_client.OK
 | 
			
		||||
        response1.json = mock.MagicMock(
 | 
			
		||||
            return_value=fixtures.SERVER_HARDWARE_LIST_JSON
 | 
			
		||||
        )
 | 
			
		||||
        mock_get.return_value = response1
 | 
			
		||||
 | 
			
		||||
        sh_uuid = oneview_client.server_hardware.list()[0].uuid
 | 
			
		||||
        assert sh_uuid
 | 
			
		||||
        oneview_client._logout()
 | 
			
		||||
        mock_post.reset_mock()
 | 
			
		||||
 | 
			
		||||
        response2 = mock.Mock(status_code=http_client.UNAUTHORIZED)
 | 
			
		||||
        response3 = mock.Mock(status_code=http_client.OK)
 | 
			
		||||
        mock_get.side_effect = [response2, response3]
 | 
			
		||||
 | 
			
		||||
        oneview_client.server_hardware.get(sh_uuid)
 | 
			
		||||
        mock_post.assert_called_once_with(
 | 
			
		||||
            'https://1.2.3.4/rest/login-sessions',
 | 
			
		||||
            data=json.dumps({"userName": "user", "password": "password"}),
 | 
			
		||||
            headers={'content-type': 'application/json'},
 | 
			
		||||
            verify=True
 | 
			
		||||
        )
 | 
			
		||||
 | 
			
		||||
    @mock.patch.object(client.Client, '_authenticate', autospec=True)
 | 
			
		||||
    @mock.patch.object(requests, 'delete', autospec=True)
 | 
			
		||||
    def test__logout(self,
 | 
			
		||||
                     mock_delete,
 | 
			
		||||
                     mock__authenticate):
 | 
			
		||||
        oneview_client = client.Client(self.manager_url,
 | 
			
		||||
                                       self.username,
 | 
			
		||||
                                       self.password)
 | 
			
		||||
        oneview_client._logout()
 | 
			
		||||
        mock_delete.assert_called_once_with(
 | 
			
		||||
            url='https://1.2.3.4/rest/login-sessions',
 | 
			
		||||
            headers=mock.ANY,
 | 
			
		||||
            verify=True
 | 
			
		||||
        )
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@mock.patch.object(client.Client, '_authenticate', autospec=True)
 | 
			
		||||
class OneViewClientTestCase(unittest.TestCase):
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -110,6 +110,21 @@ class OneViewClientAuthTestCase(unittest.TestCase):
 | 
			
		||||
        oneview_client._authenticate = mock__authenticate
 | 
			
		||||
        self.assertEqual("XYZ", self.oneview_client.get_session())
 | 
			
		||||
 | 
			
		||||
    @mock.patch.object(client.Client, '_authenticate', autospec=True)
 | 
			
		||||
    @mock.patch.object(requests, 'delete', autospec=True)
 | 
			
		||||
    def test__logout(self,
 | 
			
		||||
                     mock_delete,
 | 
			
		||||
                     mock__authenticate):
 | 
			
		||||
        oneview_client = client.Client(self.manager_url,
 | 
			
		||||
                                       self.username,
 | 
			
		||||
                                       self.password)
 | 
			
		||||
        oneview_client._logout()
 | 
			
		||||
        mock_delete.assert_called_once_with(
 | 
			
		||||
            url='https://1.2.3.4/rest/login-sessions',
 | 
			
		||||
            headers=mock.ANY,
 | 
			
		||||
            verify=True
 | 
			
		||||
        )
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class OneViewClientTestCase(unittest.TestCase):
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user