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,7 +173,12 @@ class BaseClient(object): | ||||
|             } | ||||
|             url = '%s%s' % (self.manager_url, uri) | ||||
|             body = json.dumps(body) | ||||
|             response = self._do_request(url, headers, body, request_type) | ||||
|             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() | ||||
|         except requests.RequestException as e: | ||||
| @@ -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
	 Thiago Paiva
					Thiago Paiva