Merge "Use requests module for HTTP/HTTPS"
This commit is contained in:
@@ -21,7 +21,7 @@ except ImportError:
|
|||||||
import logging
|
import logging
|
||||||
import os
|
import os
|
||||||
|
|
||||||
import httplib2
|
import requests
|
||||||
|
|
||||||
from neutronclient.common import exceptions
|
from neutronclient.common import exceptions
|
||||||
from neutronclient.common import utils
|
from neutronclient.common import utils
|
||||||
@@ -29,15 +29,15 @@ from neutronclient.openstack.common.gettextutils import _
|
|||||||
|
|
||||||
_logger = logging.getLogger(__name__)
|
_logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
# httplib2 retries requests on socket.timeout which
|
|
||||||
# is not idempotent and can lead to orhan objects.
|
|
||||||
# See: https://code.google.com/p/httplib2/issues/detail?id=124
|
|
||||||
httplib2.RETRIES = 1
|
|
||||||
|
|
||||||
if os.environ.get('NEUTRONCLIENT_DEBUG'):
|
if os.environ.get('NEUTRONCLIENT_DEBUG'):
|
||||||
ch = logging.StreamHandler()
|
ch = logging.StreamHandler()
|
||||||
_logger.setLevel(logging.DEBUG)
|
_logger.setLevel(logging.DEBUG)
|
||||||
_logger.addHandler(ch)
|
_logger.addHandler(ch)
|
||||||
|
_requests_log_level = logging.DEBUG
|
||||||
|
else:
|
||||||
|
_requests_log_level = logging.WARNING
|
||||||
|
|
||||||
|
logging.getLogger("requests").setLevel(_requests_log_level)
|
||||||
|
|
||||||
|
|
||||||
class ServiceCatalog(object):
|
class ServiceCatalog(object):
|
||||||
@@ -89,7 +89,7 @@ class ServiceCatalog(object):
|
|||||||
return matching_endpoints[0][endpoint_type]
|
return matching_endpoints[0][endpoint_type]
|
||||||
|
|
||||||
|
|
||||||
class HTTPClient(httplib2.Http):
|
class HTTPClient(object):
|
||||||
"""Handles the REST calls and responses, include authn."""
|
"""Handles the REST calls and responses, include authn."""
|
||||||
|
|
||||||
USER_AGENT = 'python-neutronclient'
|
USER_AGENT = 'python-neutronclient'
|
||||||
@@ -102,7 +102,6 @@ class HTTPClient(httplib2.Http):
|
|||||||
auth_strategy='keystone', ca_cert=None, log_credentials=False,
|
auth_strategy='keystone', ca_cert=None, log_credentials=False,
|
||||||
service_type='network',
|
service_type='network',
|
||||||
**kwargs):
|
**kwargs):
|
||||||
super(HTTPClient, self).__init__(timeout=timeout, ca_certs=ca_cert)
|
|
||||||
|
|
||||||
self.username = username
|
self.username = username
|
||||||
self.tenant_name = tenant_name
|
self.tenant_name = tenant_name
|
||||||
@@ -112,6 +111,7 @@ class HTTPClient(httplib2.Http):
|
|||||||
self.service_type = service_type
|
self.service_type = service_type
|
||||||
self.endpoint_type = endpoint_type
|
self.endpoint_type = endpoint_type
|
||||||
self.region_name = region_name
|
self.region_name = region_name
|
||||||
|
self.timeout = timeout
|
||||||
self.auth_token = token
|
self.auth_token = token
|
||||||
self.auth_tenant_id = None
|
self.auth_tenant_id = None
|
||||||
self.auth_user_id = None
|
self.auth_user_id = None
|
||||||
@@ -119,8 +119,10 @@ class HTTPClient(httplib2.Http):
|
|||||||
self.endpoint_url = endpoint_url
|
self.endpoint_url = endpoint_url
|
||||||
self.auth_strategy = auth_strategy
|
self.auth_strategy = auth_strategy
|
||||||
self.log_credentials = log_credentials
|
self.log_credentials = log_credentials
|
||||||
# httplib2 overrides
|
if insecure:
|
||||||
self.disable_ssl_certificate_validation = insecure
|
self.verify_cert = False
|
||||||
|
else:
|
||||||
|
self.verify_cert = ca_cert if ca_cert else True
|
||||||
|
|
||||||
def _cs_request(self, *args, **kwargs):
|
def _cs_request(self, *args, **kwargs):
|
||||||
kargs = {}
|
kargs = {}
|
||||||
@@ -147,7 +149,7 @@ class HTTPClient(httplib2.Http):
|
|||||||
utils.http_log_req(_logger, args, log_kargs)
|
utils.http_log_req(_logger, args, log_kargs)
|
||||||
try:
|
try:
|
||||||
resp, body = self.request(*args, **kargs)
|
resp, body = self.request(*args, **kargs)
|
||||||
except httplib2.SSLHandshakeError as e:
|
except requests.exceptions.SSLError as e:
|
||||||
raise exceptions.SslCertificateValidationError(reason=e)
|
raise exceptions.SslCertificateValidationError(reason=e)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
# Wrap the low-level connection error (socket timeout, redirect
|
# Wrap the low-level connection error (socket timeout, redirect
|
||||||
@@ -155,11 +157,6 @@ class HTTPClient(httplib2.Http):
|
|||||||
# connection exception (it is excepted in the upper layers of code)
|
# connection exception (it is excepted in the upper layers of code)
|
||||||
_logger.debug("throwing ConnectionFailed : %s", e)
|
_logger.debug("throwing ConnectionFailed : %s", e)
|
||||||
raise exceptions.ConnectionFailed(reason=e)
|
raise exceptions.ConnectionFailed(reason=e)
|
||||||
finally:
|
|
||||||
# Temporary Fix for gate failures. RPC calls and HTTP requests
|
|
||||||
# seem to be stepping on each other resulting in bogus fd's being
|
|
||||||
# picked up for making http requests
|
|
||||||
self.connections.clear()
|
|
||||||
utils.http_log_resp(_logger, resp, body)
|
utils.http_log_resp(_logger, resp, body)
|
||||||
status_code = self.get_status_code(resp)
|
status_code = self.get_status_code(resp)
|
||||||
if status_code == 401:
|
if status_code == 401:
|
||||||
@@ -181,6 +178,22 @@ class HTTPClient(httplib2.Http):
|
|||||||
elif not self.endpoint_url:
|
elif not self.endpoint_url:
|
||||||
self.endpoint_url = self._get_endpoint_url()
|
self.endpoint_url = self._get_endpoint_url()
|
||||||
|
|
||||||
|
def request(self, url, method, **kwargs):
|
||||||
|
kwargs.setdefault('headers', kwargs.get('headers', {}))
|
||||||
|
kwargs['headers']['User-Agent'] = self.USER_AGENT
|
||||||
|
kwargs['headers']['Accept'] = 'application/json'
|
||||||
|
if 'body' in kwargs:
|
||||||
|
kwargs['headers']['Content-Type'] = 'application/json'
|
||||||
|
kwargs['data'] = kwargs['body']
|
||||||
|
del kwargs['body']
|
||||||
|
resp = requests.request(
|
||||||
|
method,
|
||||||
|
url,
|
||||||
|
verify=self.verify_cert,
|
||||||
|
**kwargs)
|
||||||
|
|
||||||
|
return resp, resp.text
|
||||||
|
|
||||||
def do_request(self, url, method, **kwargs):
|
def do_request(self, url, method, **kwargs):
|
||||||
self.authenticate_and_fetch_endpoint_url()
|
self.authenticate_and_fetch_endpoint_url()
|
||||||
# Perform the request once. If we get a 401 back then it
|
# Perform the request once. If we get a 401 back then it
|
||||||
@@ -234,16 +247,10 @@ class HTTPClient(httplib2.Http):
|
|||||||
raise exceptions.NoAuthURLProvided()
|
raise exceptions.NoAuthURLProvided()
|
||||||
|
|
||||||
token_url = self.auth_url + "/tokens"
|
token_url = self.auth_url + "/tokens"
|
||||||
|
|
||||||
# Make sure we follow redirects when trying to reach Keystone
|
|
||||||
tmp_follow_all_redirects = self.follow_all_redirects
|
|
||||||
self.follow_all_redirects = True
|
|
||||||
try:
|
|
||||||
resp, resp_body = self._cs_request(token_url, "POST",
|
resp, resp_body = self._cs_request(token_url, "POST",
|
||||||
body=json.dumps(body),
|
body=json.dumps(body),
|
||||||
content_type="application/json")
|
content_type="application/json",
|
||||||
finally:
|
allow_redirects=True)
|
||||||
self.follow_all_redirects = tmp_follow_all_redirects
|
|
||||||
status_code = self.get_status_code(resp)
|
status_code = self.get_status_code(resp)
|
||||||
if status_code != 200:
|
if status_code != 200:
|
||||||
raise exceptions.Unauthorized(message=resp_body)
|
raise exceptions.Unauthorized(message=resp_body)
|
||||||
@@ -305,10 +312,10 @@ class HTTPClient(httplib2.Http):
|
|||||||
def get_status_code(self, response):
|
def get_status_code(self, response):
|
||||||
"""Returns the integer status code from the response.
|
"""Returns the integer status code from the response.
|
||||||
|
|
||||||
Either a Webob.Response (used in testing) or httplib.Response
|
Either a Webob.Response (used in testing) or requests.Response
|
||||||
is returned.
|
is returned.
|
||||||
"""
|
"""
|
||||||
if hasattr(response, 'status_int'):
|
if hasattr(response, 'status_int'):
|
||||||
return response.status_int
|
return response.status_int
|
||||||
else:
|
else:
|
||||||
return response.status
|
return response.status_code
|
||||||
|
@@ -178,7 +178,10 @@ def http_log_req(_logger, args, kwargs):
|
|||||||
def http_log_resp(_logger, resp, body):
|
def http_log_resp(_logger, resp, body):
|
||||||
if not _logger.isEnabledFor(logging.DEBUG):
|
if not _logger.isEnabledFor(logging.DEBUG):
|
||||||
return
|
return
|
||||||
_logger.debug(_("RESP:%(resp)s %(body)s\n"), {'resp': resp, 'body': body})
|
_logger.debug(_("RESP:%(code)s %(headers)s %(body)s\n"),
|
||||||
|
{'code': resp.status_code,
|
||||||
|
'headers': resp.headers,
|
||||||
|
'body': body})
|
||||||
|
|
||||||
|
|
||||||
def _safe_encode_without_obj(data):
|
def _safe_encode_without_obj(data):
|
||||||
|
@@ -15,11 +15,11 @@
|
|||||||
#
|
#
|
||||||
|
|
||||||
import copy
|
import copy
|
||||||
import httplib2
|
|
||||||
import json
|
import json
|
||||||
import uuid
|
import uuid
|
||||||
|
|
||||||
import mox
|
import mox
|
||||||
|
import requests
|
||||||
import testtools
|
import testtools
|
||||||
|
|
||||||
from neutronclient import client
|
from neutronclient import client
|
||||||
@@ -68,6 +68,13 @@ ENDPOINTS_RESULT = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
def get_response(status_code, headers=None):
|
||||||
|
response = mox.Mox().CreateMock(requests.Response)
|
||||||
|
response.headers = headers or {}
|
||||||
|
response.status_code = status_code
|
||||||
|
return response
|
||||||
|
|
||||||
|
|
||||||
class CLITestAuthNoAuth(testtools.TestCase):
|
class CLITestAuthNoAuth(testtools.TestCase):
|
||||||
|
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
@@ -86,8 +93,7 @@ class CLITestAuthNoAuth(testtools.TestCase):
|
|||||||
def test_get_noauth(self):
|
def test_get_noauth(self):
|
||||||
self.mox.StubOutWithMock(self.client, "request")
|
self.mox.StubOutWithMock(self.client, "request")
|
||||||
|
|
||||||
res200 = self.mox.CreateMock(httplib2.Response)
|
res200 = get_response(200)
|
||||||
res200.status = 200
|
|
||||||
|
|
||||||
self.client.request(
|
self.client.request(
|
||||||
mox.StrContains(ENDPOINT_URL + '/resource'), 'GET',
|
mox.StrContains(ENDPOINT_URL + '/resource'), 'GET',
|
||||||
@@ -136,8 +142,7 @@ class CLITestAuthKeystone(testtools.TestCase):
|
|||||||
def test_get_token(self):
|
def test_get_token(self):
|
||||||
self.mox.StubOutWithMock(self.client, "request")
|
self.mox.StubOutWithMock(self.client, "request")
|
||||||
|
|
||||||
res200 = self.mox.CreateMock(httplib2.Response)
|
res200 = get_response(200)
|
||||||
res200.status = 200
|
|
||||||
|
|
||||||
self.client.request(
|
self.client.request(
|
||||||
AUTH_URL + '/tokens', 'POST',
|
AUTH_URL + '/tokens', 'POST',
|
||||||
@@ -159,10 +164,8 @@ class CLITestAuthKeystone(testtools.TestCase):
|
|||||||
self.client.auth_token = TOKEN
|
self.client.auth_token = TOKEN
|
||||||
self.client.endpoint_url = ENDPOINT_URL
|
self.client.endpoint_url = ENDPOINT_URL
|
||||||
|
|
||||||
res200 = self.mox.CreateMock(httplib2.Response)
|
res200 = get_response(200)
|
||||||
res200.status = 200
|
res401 = get_response(401)
|
||||||
res401 = self.mox.CreateMock(httplib2.Response)
|
|
||||||
res401.status = 401
|
|
||||||
|
|
||||||
# If a token is expired, neutron server retruns 401
|
# If a token is expired, neutron server retruns 401
|
||||||
self.client.request(
|
self.client.request(
|
||||||
@@ -187,8 +190,7 @@ class CLITestAuthKeystone(testtools.TestCase):
|
|||||||
self.client.auth_token = TOKEN
|
self.client.auth_token = TOKEN
|
||||||
self.client.endpoint_url = ENDPOINT_URL
|
self.client.endpoint_url = ENDPOINT_URL
|
||||||
|
|
||||||
res401 = self.mox.CreateMock(httplib2.Response)
|
res401 = get_response(401)
|
||||||
res401.status = 401
|
|
||||||
|
|
||||||
# If a token is expired, neutron server returns 401
|
# If a token is expired, neutron server returns 401
|
||||||
self.client.request(
|
self.client.request(
|
||||||
@@ -212,8 +214,7 @@ class CLITestAuthKeystone(testtools.TestCase):
|
|||||||
|
|
||||||
self.client.auth_token = TOKEN
|
self.client.auth_token = TOKEN
|
||||||
|
|
||||||
res200 = self.mox.CreateMock(httplib2.Response)
|
res200 = get_response(200)
|
||||||
res200.status = 200
|
|
||||||
|
|
||||||
self.client.request(
|
self.client.request(
|
||||||
mox.StrContains(AUTH_URL + '/tokens/%s/endpoints' % TOKEN), 'GET',
|
mox.StrContains(AUTH_URL + '/tokens/%s/endpoints' % TOKEN), 'GET',
|
||||||
@@ -236,9 +237,7 @@ class CLITestAuthKeystone(testtools.TestCase):
|
|||||||
self.mox.StubOutWithMock(self.client, "request")
|
self.mox.StubOutWithMock(self.client, "request")
|
||||||
|
|
||||||
self.client.auth_token = TOKEN
|
self.client.auth_token = TOKEN
|
||||||
|
res200 = get_response(200)
|
||||||
res200 = self.mox.CreateMock(httplib2.Response)
|
|
||||||
res200.status = 200
|
|
||||||
|
|
||||||
self.client.request(
|
self.client.request(
|
||||||
mox.StrContains(ENDPOINT_OVERRIDE + '/resource'), 'GET',
|
mox.StrContains(ENDPOINT_OVERRIDE + '/resource'), 'GET',
|
||||||
@@ -255,9 +254,7 @@ class CLITestAuthKeystone(testtools.TestCase):
|
|||||||
self.mox.StubOutWithMock(self.client, "request")
|
self.mox.StubOutWithMock(self.client, "request")
|
||||||
|
|
||||||
self.client.auth_token = TOKEN
|
self.client.auth_token = TOKEN
|
||||||
|
res200 = get_response(200)
|
||||||
res200 = self.mox.CreateMock(httplib2.Response)
|
|
||||||
res200.status = 200
|
|
||||||
|
|
||||||
self.client.request(
|
self.client.request(
|
||||||
mox.StrContains(AUTH_URL + '/tokens/%s/endpoints' % TOKEN), 'GET',
|
mox.StrContains(AUTH_URL + '/tokens/%s/endpoints' % TOKEN), 'GET',
|
||||||
@@ -274,10 +271,8 @@ class CLITestAuthKeystone(testtools.TestCase):
|
|||||||
|
|
||||||
self.client.auth_token = TOKEN
|
self.client.auth_token = TOKEN
|
||||||
|
|
||||||
res200 = self.mox.CreateMock(httplib2.Response)
|
res200 = get_response(200)
|
||||||
res200.status = 200
|
res401 = get_response(401)
|
||||||
res401 = self.mox.CreateMock(httplib2.Response)
|
|
||||||
res401.status = 401
|
|
||||||
|
|
||||||
self.client.request(
|
self.client.request(
|
||||||
mox.StrContains(AUTH_URL + '/tokens/%s/endpoints' % TOKEN), 'GET',
|
mox.StrContains(AUTH_URL + '/tokens/%s/endpoints' % TOKEN), 'GET',
|
||||||
@@ -433,8 +428,7 @@ class CLITestAuthKeystone(testtools.TestCase):
|
|||||||
self.mox.StubOutWithMock(self.client, "request")
|
self.mox.StubOutWithMock(self.client, "request")
|
||||||
self.mox.StubOutWithMock(utils, "http_log_req")
|
self.mox.StubOutWithMock(utils, "http_log_req")
|
||||||
|
|
||||||
res200 = self.mox.CreateMock(httplib2.Response)
|
res200 = get_response(200)
|
||||||
res200.status = 200
|
|
||||||
|
|
||||||
utils.http_log_req(mox.IgnoreArg(), mox.IgnoreArg(), mox.Func(
|
utils.http_log_req(mox.IgnoreArg(), mox.IgnoreArg(), mox.Func(
|
||||||
verify_no_credentials))
|
verify_no_credentials))
|
||||||
|
@@ -48,8 +48,9 @@ class FakeStdout:
|
|||||||
|
|
||||||
|
|
||||||
class MyResp(object):
|
class MyResp(object):
|
||||||
def __init__(self, status, reason=None):
|
def __init__(self, status_code, headers=None, reason=None):
|
||||||
self.status = status
|
self.status_code = status_code
|
||||||
|
self.headers = headers or {}
|
||||||
self.reason = reason
|
self.reason = reason
|
||||||
|
|
||||||
|
|
||||||
@@ -533,7 +534,7 @@ class ClientV2TestJson(CLITestV20Base):
|
|||||||
end_url('/test', query=expect_query, format=self.format),
|
end_url('/test', query=expect_query, format=self.format),
|
||||||
'PUT', body='',
|
'PUT', body='',
|
||||||
headers=mox.ContainsKeyValue('X-Auth-Token', 'token')
|
headers=mox.ContainsKeyValue('X-Auth-Token', 'token')
|
||||||
).AndReturn((MyResp(400, 'An error'), ''))
|
).AndReturn((MyResp(400, reason='An error'), ''))
|
||||||
|
|
||||||
self.mox.ReplayAll()
|
self.mox.ReplayAll()
|
||||||
error = self.assertRaises(exceptions.NeutronClientException,
|
error = self.assertRaises(exceptions.NeutronClientException,
|
||||||
|
@@ -13,7 +13,6 @@
|
|||||||
# License for the specific language governing permissions and limitations
|
# License for the specific language governing permissions and limitations
|
||||||
# under the License.
|
# under the License.
|
||||||
|
|
||||||
import httplib2
|
|
||||||
import mox
|
import mox
|
||||||
import testtools
|
import testtools
|
||||||
|
|
||||||
@@ -33,13 +32,13 @@ class TestHTTPClient(testtools.TestCase):
|
|||||||
super(TestHTTPClient, self).setUp()
|
super(TestHTTPClient, self).setUp()
|
||||||
|
|
||||||
self.mox = mox.Mox()
|
self.mox = mox.Mox()
|
||||||
self.mox.StubOutWithMock(httplib2.Http, 'request')
|
self.mox.StubOutWithMock(HTTPClient, 'request')
|
||||||
self.addCleanup(self.mox.UnsetStubs)
|
self.addCleanup(self.mox.UnsetStubs)
|
||||||
|
|
||||||
self.http = HTTPClient(token=AUTH_TOKEN, endpoint_url=END_URL)
|
self.http = HTTPClient(token=AUTH_TOKEN, endpoint_url=END_URL)
|
||||||
|
|
||||||
def test_request_error(self):
|
def test_request_error(self):
|
||||||
httplib2.Http.request(
|
HTTPClient.request(
|
||||||
URL, METHOD, headers=mox.IgnoreArg()
|
URL, METHOD, headers=mox.IgnoreArg()
|
||||||
).AndRaise(Exception('error msg'))
|
).AndRaise(Exception('error msg'))
|
||||||
self.mox.ReplayAll()
|
self.mox.ReplayAll()
|
||||||
@@ -54,7 +53,7 @@ class TestHTTPClient(testtools.TestCase):
|
|||||||
def test_request_success(self):
|
def test_request_success(self):
|
||||||
rv_should_be = MyResp(200), 'test content'
|
rv_should_be = MyResp(200), 'test content'
|
||||||
|
|
||||||
httplib2.Http.request(
|
HTTPClient.request(
|
||||||
URL, METHOD, headers=mox.IgnoreArg()
|
URL, METHOD, headers=mox.IgnoreArg()
|
||||||
).AndReturn(rv_should_be)
|
).AndReturn(rv_should_be)
|
||||||
self.mox.ReplayAll()
|
self.mox.ReplayAll()
|
||||||
@@ -64,7 +63,7 @@ class TestHTTPClient(testtools.TestCase):
|
|||||||
|
|
||||||
def test_request_unauthorized(self):
|
def test_request_unauthorized(self):
|
||||||
rv_should_be = MyResp(401), 'unauthorized message'
|
rv_should_be = MyResp(401), 'unauthorized message'
|
||||||
httplib2.Http.request(
|
HTTPClient.request(
|
||||||
URL, METHOD, headers=mox.IgnoreArg()
|
URL, METHOD, headers=mox.IgnoreArg()
|
||||||
).AndReturn(rv_should_be)
|
).AndReturn(rv_should_be)
|
||||||
self.mox.ReplayAll()
|
self.mox.ReplayAll()
|
||||||
@@ -76,7 +75,7 @@ class TestHTTPClient(testtools.TestCase):
|
|||||||
|
|
||||||
def test_request_forbidden_is_returned_to_caller(self):
|
def test_request_forbidden_is_returned_to_caller(self):
|
||||||
rv_should_be = MyResp(403), 'forbidden message'
|
rv_should_be = MyResp(403), 'forbidden message'
|
||||||
httplib2.Http.request(
|
HTTPClient.request(
|
||||||
URL, METHOD, headers=mox.IgnoreArg()
|
URL, METHOD, headers=mox.IgnoreArg()
|
||||||
).AndReturn(rv_should_be)
|
).AndReturn(rv_should_be)
|
||||||
self.mox.ReplayAll()
|
self.mox.ReplayAll()
|
||||||
|
@@ -14,8 +14,8 @@
|
|||||||
# under the License.
|
# under the License.
|
||||||
|
|
||||||
import fixtures
|
import fixtures
|
||||||
import httplib2
|
|
||||||
import mox
|
import mox
|
||||||
|
import requests
|
||||||
import testtools
|
import testtools
|
||||||
|
|
||||||
from neutronclient.client import HTTPClient
|
from neutronclient.client import HTTPClient
|
||||||
@@ -126,10 +126,10 @@ class TestSSL(testtools.TestCase):
|
|||||||
def test_proper_exception_is_raised_when_cert_validation_fails(self):
|
def test_proper_exception_is_raised_when_cert_validation_fails(self):
|
||||||
http = HTTPClient(token=AUTH_TOKEN, endpoint_url=END_URL)
|
http = HTTPClient(token=AUTH_TOKEN, endpoint_url=END_URL)
|
||||||
|
|
||||||
self.mox.StubOutWithMock(httplib2.Http, 'request')
|
self.mox.StubOutWithMock(HTTPClient, 'request')
|
||||||
httplib2.Http.request(
|
HTTPClient.request(
|
||||||
URL, METHOD, headers=mox.IgnoreArg()
|
URL, METHOD, headers=mox.IgnoreArg()
|
||||||
).AndRaise(httplib2.SSLHandshakeError)
|
).AndRaise(requests.exceptions.SSLError)
|
||||||
self.mox.ReplayAll()
|
self.mox.ReplayAll()
|
||||||
|
|
||||||
self.assertRaises(
|
self.assertRaises(
|
||||||
|
@@ -14,11 +14,11 @@
|
|||||||
# under the License.
|
# under the License.
|
||||||
#
|
#
|
||||||
|
|
||||||
import httplib
|
|
||||||
import logging
|
import logging
|
||||||
import time
|
import time
|
||||||
import urllib
|
import urllib
|
||||||
|
|
||||||
|
import requests
|
||||||
import six.moves.urllib.parse as urlparse
|
import six.moves.urllib.parse as urlparse
|
||||||
|
|
||||||
from neutronclient import client
|
from neutronclient import client
|
||||||
@@ -1231,10 +1231,10 @@ class Client(object):
|
|||||||
self.httpclient.content_type = self.content_type()
|
self.httpclient.content_type = self.content_type()
|
||||||
resp, replybody = self.httpclient.do_request(action, method, body=body)
|
resp, replybody = self.httpclient.do_request(action, method, body=body)
|
||||||
status_code = self.get_status_code(resp)
|
status_code = self.get_status_code(resp)
|
||||||
if status_code in (httplib.OK,
|
if status_code in (requests.codes.ok,
|
||||||
httplib.CREATED,
|
requests.codes.created,
|
||||||
httplib.ACCEPTED,
|
requests.codes.accepted,
|
||||||
httplib.NO_CONTENT):
|
requests.codes.no_content):
|
||||||
return self.deserialize(replybody, status_code)
|
return self.deserialize(replybody, status_code)
|
||||||
else:
|
else:
|
||||||
if not replybody:
|
if not replybody:
|
||||||
@@ -1247,13 +1247,13 @@ class Client(object):
|
|||||||
def get_status_code(self, response):
|
def get_status_code(self, response):
|
||||||
"""Returns the integer status code from the response.
|
"""Returns the integer status code from the response.
|
||||||
|
|
||||||
Either a Webob.Response (used in testing) or httplib.Response
|
Either a Webob.Response (used in testing) or requests.Response
|
||||||
is returned.
|
is returned.
|
||||||
"""
|
"""
|
||||||
if hasattr(response, 'status_int'):
|
if hasattr(response, 'status_int'):
|
||||||
return response.status_int
|
return response.status_int
|
||||||
else:
|
else:
|
||||||
return response.status
|
return response.status_code
|
||||||
|
|
||||||
def serialize(self, data):
|
def serialize(self, data):
|
||||||
"""Serializes a dictionary into either xml or json.
|
"""Serializes a dictionary into either xml or json.
|
||||||
|
@@ -4,6 +4,7 @@ cliff>=1.4.3
|
|||||||
httplib2>=0.7.5
|
httplib2>=0.7.5
|
||||||
iso8601>=0.1.9
|
iso8601>=0.1.9
|
||||||
netaddr>=0.7.6
|
netaddr>=0.7.6
|
||||||
|
requests>=1.1
|
||||||
simplejson>=2.0.9
|
simplejson>=2.0.9
|
||||||
six>=1.6.0
|
six>=1.6.0
|
||||||
Babel>=1.3
|
Babel>=1.3
|
||||||
|
Reference in New Issue
Block a user