Revert "Replaces httplib2 with Python Requests support"
This reverts commit 5f62c0b65b
.
Change-Id: Ib51adff04dc17651f52945d1459b536a8c675c93
This commit is contained in:
parent
13396d5846
commit
f1f1bd0ce6
|
@ -3,11 +3,11 @@ HP LeftHand/StoreVirtual REST Client
|
|||
This is a Client library that can talk to the HP LeftHand/StoreVirtual Storage array.
|
||||
The HP LeftHand storage array has a REST web service interface.
|
||||
This client library implements a simple interface to talk with that REST
|
||||
interface using the python Requests http library.
|
||||
interface using the python httplib2 http library.
|
||||
|
||||
Requirements
|
||||
============
|
||||
This branch requires 11.5 version or later of the LeftHand OS firmware.
|
||||
This branch requires 11.5 version of the LeftHand OS firmware.
|
||||
|
||||
Capabilities
|
||||
============
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
.. automodule:: hplefthandclient.client
|
||||
:synopsis: HP LeftHand REST Web client
|
||||
|
||||
.. autoclass:: hplefthandclient.client.HPLeftHandClient(api_url, secure=False)
|
||||
.. autoclass:: hplefthandclient.client.HPLeftHandClient(api_url)
|
||||
|
||||
.. automethod:: debug_rest
|
||||
.. automethod:: login
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
.. automodule:: hplefthandclient.http
|
||||
:synopsis: HTTP REST Base Class
|
||||
|
||||
.. autoclass:: hplefthandclient.http.HTTPJSONRESTClient(api_url, [secure=True[,http_log_debug=False]])
|
||||
.. autoclass:: hplefthandclient.http.HTTPJSONRESTClient(api_url, [insecure=False[,http_log_debug=False]])
|
||||
|
||||
.. automethod:: authenticate
|
||||
.. automethod:: unauthenticate
|
||||
|
|
|
@ -58,7 +58,7 @@ Changes in Version 1.0.5
|
|||
* Added improved error handling during login attempts. Errors will now be
|
||||
more descriptive in why a login failed.
|
||||
|
||||
Changes in Version 1.1.0
|
||||
Changes in Version 1.0.6
|
||||
------------------------
|
||||
|
||||
* Python3.4+ compliant
|
||||
|
@ -66,10 +66,6 @@ Changes in Version 1.1.0
|
|||
pull and install from
|
||||
* Updated tox to run py34 tests
|
||||
* Modified basic Python calls to work with both Python2 and Python3.4
|
||||
* Replaced all httplib2 calls with Python Request calls
|
||||
* SSL certificate verification can be enabled by passing secure=True
|
||||
* SSL certificate verification can be done against a self provided .crt file
|
||||
with secure='/path/to/ca-certificates.crt'
|
||||
* Fixed error that was happening during client initialization when an error
|
||||
was missing a description.
|
||||
* Fixes clusterId bug in createVolume (Issue #3)
|
||||
|
|
|
@ -31,13 +31,6 @@ Doing so is easy:
|
|||
#LeftHand server with IP 10.10.10.10 on port 8008.
|
||||
cl = client.HPLeftHandClient("https://10.10.10.10:8008/api/v1")
|
||||
|
||||
# SSL certification verification is defaulted to False. In order to
|
||||
# override this, set secure=True. or secure='/path/to/cert.crt'
|
||||
# cl = client.HP3ParClient("https://10.10.10.10:8080/api/v1",
|
||||
# secure=True)
|
||||
# cl = client.HP3ParClient("https://10.10.10.10:8080/api/v1",
|
||||
# secure='/etc/ssl/certs/ca-certificates.crt')
|
||||
|
||||
try:
|
||||
cl.login(username, password)
|
||||
print "Login worked!"
|
||||
|
|
|
@ -24,7 +24,7 @@ HP LeftHand REST Client
|
|||
|
||||
"""
|
||||
|
||||
version_tuple = (1, 1, 0)
|
||||
version_tuple = (1, 0, 6)
|
||||
|
||||
|
||||
def get_version_string():
|
||||
|
|
|
@ -40,10 +40,9 @@ from hplefthandclient import exceptions, http
|
|||
|
||||
class HPLeftHandClient:
|
||||
|
||||
def __init__(self, api_url, debug=False, secure=False):
|
||||
def __init__(self, api_url, debug=False):
|
||||
self.api_url = api_url
|
||||
self.secure = secure
|
||||
self.http = http.HTTPJSONRESTClient(self.api_url, secure=self.secure)
|
||||
self.http = http.HTTPJSONRESTClient(self.api_url)
|
||||
self.api_version = None
|
||||
|
||||
self.debug_rest(debug)
|
||||
|
@ -76,8 +75,8 @@ class HPLeftHandClient:
|
|||
except Exception as ex:
|
||||
ex_desc = ex.get_description()
|
||||
|
||||
if (ex_desc and ("Unable to find the server at" in ex_desc or
|
||||
"Only absolute URIs are allowed" in ex_desc)):
|
||||
if (ex_desc and "Unable to find the server at" in ex_desc or
|
||||
"Only absolute URIs are allowed" in ex_desc):
|
||||
raise exceptions.HTTPBadRequest(ex_desc)
|
||||
if (ex_desc and "SSL Certificate Verification Failed" in ex_desc):
|
||||
raise exceptions.SSLCertFailed()
|
||||
|
|
|
@ -105,6 +105,7 @@ class ClientException(Exception):
|
|||
|
||||
return formatted_string
|
||||
|
||||
|
||||
##
|
||||
# SSL Errors
|
||||
##
|
||||
|
@ -118,53 +119,6 @@ class SSLCertFailed(ClientException):
|
|||
message = "SSL Certificate Verification Failed"
|
||||
|
||||
|
||||
##
|
||||
# Python Requests Errors
|
||||
##
|
||||
|
||||
|
||||
class RequestException(ClientException):
|
||||
"""
|
||||
There was an ambiguous exception that occurred in Requests
|
||||
"""
|
||||
pass
|
||||
|
||||
|
||||
class ConnectionError(ClientException):
|
||||
"""
|
||||
There was an error connecting to the server
|
||||
"""
|
||||
pass
|
||||
|
||||
|
||||
class HTTPError(ClientException):
|
||||
"""
|
||||
An HTTP error occurred
|
||||
"""
|
||||
pass
|
||||
|
||||
|
||||
class URLRequired(ClientException):
|
||||
"""
|
||||
A valid URL is required to make a request
|
||||
"""
|
||||
pass
|
||||
|
||||
|
||||
class TooManyRedirects(ClientException):
|
||||
"""
|
||||
Too many redirects
|
||||
"""
|
||||
pass
|
||||
|
||||
|
||||
class Timeout(ClientException):
|
||||
"""
|
||||
The request timed out
|
||||
"""
|
||||
pass
|
||||
|
||||
|
||||
##
|
||||
# 400 Errors
|
||||
##
|
||||
|
@ -401,7 +355,7 @@ _code_map = dict((c.http_status, c) for c in [
|
|||
def from_response(response, body):
|
||||
"""
|
||||
Return an instance of an ClientException or subclass
|
||||
based on a Python Requests response.
|
||||
based on an httplib2 response.
|
||||
|
||||
Usage::
|
||||
|
||||
|
|
|
@ -27,9 +27,9 @@ HPLeftHand HTTP Client
|
|||
"""
|
||||
|
||||
import logging
|
||||
import requests
|
||||
import httplib2
|
||||
import time
|
||||
# requests.packages.urllib3.disable_warnings()
|
||||
import pprint
|
||||
|
||||
try:
|
||||
import json
|
||||
|
@ -39,7 +39,7 @@ except ImportError:
|
|||
from hplefthandclient import exceptions
|
||||
|
||||
|
||||
class HTTPJSONRESTClient(object):
|
||||
class HTTPJSONRESTClient(httplib2.Http):
|
||||
"""
|
||||
An HTTP REST Client that sends and recieves JSON data as the body of the
|
||||
HTTP request.
|
||||
|
@ -47,8 +47,8 @@ class HTTPJSONRESTClient(object):
|
|||
:param api_url: The url to the LH OS REST service
|
||||
ie. https://<hostname or IP>:<port>/lhos
|
||||
:type api_url: str
|
||||
:param secure: Validate SSL cert? Default will not validate
|
||||
:type secure: bool
|
||||
:param insecure: Use https? requires a local certificate
|
||||
:type insecure: bool
|
||||
|
||||
"""
|
||||
|
||||
|
@ -59,7 +59,9 @@ class HTTPJSONRESTClient(object):
|
|||
http_log_debug = False
|
||||
_logger = logging.getLogger(__name__)
|
||||
|
||||
def __init__(self, api_url, secure=False, http_log_debug=False):
|
||||
def __init__(self, api_url, insecure=False, http_log_debug=False):
|
||||
super(HTTPJSONRESTClient,
|
||||
self).__init__(disable_ssl_certificate_validation=True)
|
||||
self.session_key = None
|
||||
|
||||
#should be http://<Server:Port>/lhos
|
||||
|
@ -67,7 +69,10 @@ class HTTPJSONRESTClient(object):
|
|||
self.set_debug_flag(http_log_debug)
|
||||
|
||||
self.times = [] # [("item", starttime, endtime), ...]
|
||||
self.secure = secure
|
||||
|
||||
# httplib2 overrides
|
||||
self.force_exception_to_status_code = True
|
||||
#self.disable_ssl_certificate_validation = insecure
|
||||
|
||||
def set_url(self, api_url):
|
||||
#should be http://<Server:Port>/lhos
|
||||
|
@ -163,8 +168,7 @@ class HTTPJSONRESTClient(object):
|
|||
def _http_log_resp(self, resp, body):
|
||||
if not self.http_log_debug:
|
||||
return
|
||||
HTTPJSONRESTClient._logger.debug("RESP:%s\n",
|
||||
str(resp).replace('\',', '\'\n'))
|
||||
HTTPJSONRESTClient._logger.debug("RESP:%s\n", pprint.pformat(resp))
|
||||
HTTPJSONRESTClient._logger.debug("RESP BODY:%s\n", body)
|
||||
|
||||
def request(self, *args, **kwargs):
|
||||
|
@ -182,51 +186,11 @@ class HTTPJSONRESTClient(object):
|
|||
if 'body' in kwargs:
|
||||
kwargs['headers']['Content-Type'] = 'application/json'
|
||||
kwargs['body'] = json.dumps(kwargs['body'])
|
||||
payload = kwargs['body']
|
||||
else:
|
||||
payload = None
|
||||
|
||||
# args[0] contains the URL, args[1] contains the HTTP verb/method
|
||||
http_url = args[0]
|
||||
http_method = args[1]
|
||||
|
||||
self._http_log_req(args, kwargs)
|
||||
try:
|
||||
r = requests.request(http_method, http_url, data=payload,
|
||||
headers=kwargs['headers'], verify=self.secure)
|
||||
except requests.exceptions.SSLError as err:
|
||||
HTTPJSONRESTClient._logger.error("SSL certificate verification"
|
||||
" failed: (%s). You must have a"
|
||||
" valid SSL certificate or"
|
||||
" disable SSL verification.", err)
|
||||
raise exceptions.SSLCertFailed("SSL Certificate Verification"
|
||||
" Failed")
|
||||
except requests.exceptions.RequestException as err:
|
||||
raise exceptions.RequestException("Request Exception: %s" % err)
|
||||
except requests.exceptions.ConnectionError as err:
|
||||
raise exceptions.ConnectionError("Connection Error: %s" % err)
|
||||
except requests.exceptions.HTTPError as err:
|
||||
raise exceptions.HTTPError("HTTP Error: %s" % err)
|
||||
except requests.exceptions.URLRequired as err:
|
||||
raise exceptions.URLRequired("URL Required: %s" % err)
|
||||
except requests.exceptions.TooManyRedirects as err:
|
||||
raise exceptions.TooManyRedirects("Too Many Redirects: %s" % err)
|
||||
except requests.exceptions.Timeout as err:
|
||||
raise exceptions.Timeout("Timeout: %s" % err)
|
||||
|
||||
resp = r.headers
|
||||
body = r.text
|
||||
resp, body = super(HTTPJSONRESTClient, self).request(*args, **kwargs)
|
||||
if isinstance(body, bytes):
|
||||
body = body.decode('utf-8')
|
||||
|
||||
# resp['status'], status['content-location'], and resp.status need to
|
||||
# be manually set as Python Requests doesnt provide them automatically
|
||||
resp['status'] = str(r.status_code)
|
||||
resp.status = r.status_code
|
||||
if 'location' not in resp:
|
||||
resp['content-location'] = r.url
|
||||
|
||||
r.close()
|
||||
self._http_log_resp(resp, body)
|
||||
|
||||
# Try and conver the body response to an object
|
||||
|
|
|
@ -1 +1 @@
|
|||
requests>=2.5.2
|
||||
httplib2>=0.6.0
|
||||
|
|
4
setup.py
4
setup.py
|
@ -15,8 +15,8 @@ setup(
|
|||
author_email="kurt.f.martin@hp.com",
|
||||
maintainer="Kurt Martin",
|
||||
keywords=["hp", "lefthand", "storevirtual", "rest"],
|
||||
requires=['requests(>=2.5.2)'],
|
||||
install_requires=['requests >= 2.5.2'],
|
||||
requires=['httplib2(>=0.6.0)'],
|
||||
install_requires=['httplib2 >= 0.6.0'],
|
||||
tests_require=["nose", "nose-testconfig", "flask", "Werkzeug", "flake8"],
|
||||
license="Apache License, Version 2.0",
|
||||
packages=find_packages(),
|
||||
|
|
Loading…
Reference in New Issue