Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 13 additions & 15 deletions hpe3parclient/client.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# (c) Copyright 2012-2025 Hewlett Packard Enterprise Development LP
# (c) Copyright 2012-2025, 2026 Hewlett Packard Enterprise Development LP
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
Expand Down Expand Up @@ -221,6 +221,9 @@ def __init__(self, api_url, debug=False, secure=False, timeout=None,

def is_primera_array(self):
return self.primera_supported

def get_session_key(self):
return self.http.get_session_key()

def setSSHOptions(self, ip, login, password, port=22,
conn_timeout=None, privatekey=None,
Expand Down Expand Up @@ -253,22 +256,17 @@ def getWsApiVersion(self):
:returns: Version dict

"""
try:
# remove everything down to host:port
host_url = self.api_url.split('/api')
self.http.set_url(host_url[0])
# get the api version
response, body = self.http.get('/api')
# remove everything down to host:port
host_url = self.api_url.split('/api')
# Build absolute URL and call without mutating http client's base
response, body = self.http.get(host_url[0] + '/api')

api_version = body
if (api_version['build'] >=
self.HPE3PAR_WS_PRIMERA_MIN_BUILD_VERSION):
self.primera_supported = True
api_version = body
if (api_version['build'] >=
self.HPE3PAR_WS_PRIMERA_MIN_BUILD_VERSION):
self.primera_supported = True

return body
finally:
# reset the url
self.http.set_url(self.api_url)
return body

def debug_rest(self, flag):
"""This is useful for debugging requests to 3PAR.
Expand Down
47 changes: 39 additions & 8 deletions hpe3parclient/http.py
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,8 @@ def __init__(self, api_url, secure=False, http_log_debug=False,
if suppress_ssl_warnings:
requests.packages.urllib3.disable_warnings()

HTTPJSONRESTClient._logger.debug("Initializing Session Key in __init__:")

self.session_key = None

# should be http://<Server:Port>/api/v1
Expand All @@ -86,6 +88,9 @@ def set_url(self, api_url):
# should be http://<Server:Port>/api/v1
self.api_url = api_url.rstrip('/')

def get_session_key(self):
return self.session_key

def set_debug_flag(self, flag):
"""
This turns on/off http request/response debugging output to console
Expand All @@ -111,6 +116,8 @@ def authenticate(self, user, password, optional=None):

"""
# this prevens re-auth attempt if auth fails
HTTPJSONRESTClient._logger.debug("Session Key in authenticate: %s\n" %
(self.session_key))
self.auth_try = 1
self.session_key = None

Expand All @@ -136,9 +143,16 @@ def unauthenticate(self):
This clears the authenticated session with the 3PAR server.

"""
# delete the session on the 3Par
self.delete('/credentials/%s' % self.session_key)
self.session_key = None
try:
# delete the session on the 3Par
HTTPJSONRESTClient._logger.debug("Session Key in unauthenticate: %s\n" %
(self.session_key))
self.delete('/credentials/%s' % self.session_key)
self.session_key = None
except Exception as ex:
HTTPJSONRESTClient._logger.error("Error during unauthenticate: %s\n"
% (str(ex)))
raise ex

def get_timings(self):
"""
Expand Down Expand Up @@ -275,7 +289,7 @@ def request(self, *args, **kwargs):
self.delay = self.delay * self.backoff + 1

# Raise exception, we have exhausted all retries.
if self.tries is 0:
if self.tries == 0:
raise ex
except requests.exceptions.HTTPError as err:
raise exceptions.HTTPError("HTTP Error: %s" % err)
Expand All @@ -292,20 +306,33 @@ def request(self, *args, **kwargs):

return resp, body

def _build_full_url(self, url):
"""Build full URL, supporting both absolute and relative URLs."""
if url.startswith('http://') or url.startswith('https://'):
return url.rstrip('/')
else:
return self.api_url + url

def _time_request(self, url, method, **kwargs):
start_time = time.time()
HTTPJSONRESTClient._logger.debug("url in _time_request: %s\n" %
(url))
resp, body = self.request(url, method, **kwargs)
self.times.append(("%s %s" % (method, url),
start_time, time.time()))
return resp, body

def _do_reauth(self, url, method, ex, **kwargs):
# print("_do_reauth called")
HTTPJSONRESTClient._logger.debug("session key in _do_reauth: %s\n" %
(self.session_key))
HTTPJSONRESTClient._logger.debug("auth_try in _do_reauth: %s\n" %
(self.auth_try))
try:
if self.auth_try != 1:
self._reauth()
resp, body = self._time_request(self.api_url + url, method,
**kwargs)
full_url = self._build_full_url(url)
resp, body = self._time_request(full_url, method, **kwargs)
return resp, body
else:
raise ex
Expand All @@ -317,8 +344,12 @@ def _cs_request(self, url, method, **kwargs):
# might be because the auth token expired, so try to
# re-authenticate and try again. If it still fails, bail.
try:
resp, body = self._time_request(self.api_url + url, method,
**kwargs)
HTTPJSONRESTClient._logger.debug("url in _cs_request: %s\n" %
(url))
full_url = self._build_full_url(url)
HTTPJSONRESTClient._logger.debug("full url in _cs_request: %s\n" %
(full_url))
resp, body = self._time_request(full_url, method, **kwargs)
return resp, body
except exceptions.HTTPUnauthorized as ex:
# print("_CS_REQUEST HTTPUnauthorized")
Expand Down