Fix TypeError when call keystoneclient session.request()

A TypeError raised when run cmd 'heat resource-show':
 TypeError: request() got an unexpected keyword argument
 'follow_redirects'
This problem was introduced by the
change I90bc9d9fcd1058c3eca288f08dd134810f1b0000 to move
SessionClient from HTTPClient to adapter, due there is no
keyword argument 'follow_redirects' in keystoneclient
session.request() method.

Change-Id: I91f13da740bf1e66dffd68cdf666a24d68aa543d
Closes-Bug: #1471650
This commit is contained in:
huangtianhua
2015-07-06 17:56:45 +08:00
parent ed72b1a01d
commit 6c4d183f6e
3 changed files with 38 additions and 20 deletions

View File

@@ -176,7 +176,7 @@ class HTTPClient(object):
# Allow caller to specify not to follow redirects, in which case we
# just return the redirect response. Useful for using stacks:lookup.
follow_redirects = kwargs.pop('follow_redirects', True)
redirect = kwargs.pop('redirect', True)
# Since requests does not follow the RFC when doing redirection to sent
# back the same method on a redirect we are simply bypassing it. For
@@ -221,8 +221,8 @@ class HTTPClient(object):
raise exc.from_response(resp)
elif resp.status_code in (301, 302, 305):
# Redirected. Reissue the request to the new location,
# unless caller specified follow_redirects=False
if follow_redirects:
# unless caller specified redirect=False
if redirect:
location = resp.headers.get('location')
path = self.strip_endpoint(location)
resp = self._http_request(path, method, **kwargs)
@@ -300,6 +300,7 @@ class SessionClient(adapter.LegacyJsonAdapter):
"""HTTP client based on Keystone client session."""
def request(self, url, method, **kwargs):
redirect = kwargs.get('redirect')
kwargs.setdefault('user_agent', USER_AGENT)
try:
@@ -307,13 +308,15 @@ class SessionClient(adapter.LegacyJsonAdapter):
except KeyError:
pass
resp, body = super(SessionClient, self).request(url, method,
resp, body = super(SessionClient, self).request(
url, method,
raise_exc=False,
**kwargs)
if 400 <= resp.status_code < 600:
raise exc.from_response(resp)
elif resp.status_code in (301, 302, 305):
if redirect:
location = resp.headers.get('location')
path = self.strip_endpoint(location)
resp = self.request(path, method, **kwargs)

View File

@@ -1,4 +1,4 @@
#-*- coding:utf-8 -*-
# -*- coding:utf-8 -*-
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
@@ -712,7 +712,7 @@ class SessionClientTest(testtools.TestCase):
# Assert that the raised exception can be converted to string
self.assertIsNotNone(six.text_type(e))
def test_302_location(self):
def test_redirect_302_location(self):
fake1 = fakes.FakeHTTPResponse(
302,
'OK',
@@ -731,7 +731,7 @@ class SessionClientTest(testtools.TestCase):
client = http.SessionClient(session=mock.ANY,
auth=mock.ANY,
endpoint_override='http://no.where/')
resp = client.request('', 'GET')
resp = client.request('', 'GET', redirect=True)
self.assertEqual(200, resp.status_code)
self.assertEqual({'Mount': 'Fuji'}, utils.get_response_body(resp))
@@ -740,7 +740,8 @@ class SessionClientTest(testtools.TestCase):
self.assertEqual(('ishere', 'GET'), self.request.call_args_list[1][0])
for call in self.request.call_args_list:
self.assertEqual({'user_agent': 'python-heatclient',
'raise_exc': False}, call[1])
'raise_exc': False,
'redirect': True}, call[1])
def test_302_location_no_endpoint(self):
fake1 = fakes.FakeHTTPResponse(
@@ -760,7 +761,7 @@ class SessionClientTest(testtools.TestCase):
client = http.SessionClient(session=mock.ANY,
auth=mock.ANY)
resp = client.request('', 'GET')
resp = client.request('', 'GET', redirect=True)
self.assertEqual(200, resp.status_code)
self.assertEqual({'Mount': 'Fuji'}, utils.get_response_body(resp))
@@ -770,9 +771,10 @@ class SessionClientTest(testtools.TestCase):
'GET'), self.request.call_args_list[1][0])
for call in self.request.call_args_list:
self.assertEqual({'user_agent': 'python-heatclient',
'raise_exc': False}, call[1])
'raise_exc': False,
'redirect': True}, call[1])
def test_302_no_location(self):
def test_redirect_302_no_location(self):
fake = fakes.FakeHTTPResponse(
302,
'OK',
@@ -784,9 +786,23 @@ class SessionClientTest(testtools.TestCase):
client = http.SessionClient(session=mock.ANY,
auth=mock.ANY)
e = self.assertRaises(exc.InvalidEndpoint,
client.request, '', 'GET')
client.request, '', 'GET', redirect=True)
self.assertEqual("Location not returned with 302", six.text_type(e))
def test_no_redirect_302_no_location(self):
fake = fakes.FakeHTTPResponse(
302,
'OK',
{'location': 'http://no.where/ishere'},
''
)
self.request.side_effect = [(fake, '')]
client = http.SessionClient(session=mock.ANY,
auth=mock.ANY)
self.assertEqual(fake, client.request('', 'GET'))
def test_300_error_response(self):
fake = fakes.FakeHTTPResponse(
300,

View File

@@ -235,9 +235,8 @@ class StackChildManager(base.BaseManager):
# We want to capture the redirect, not actually get the stack,
# since all we want is the stacks:lookup response to get the
# fully qualified ID, and not all users are allowed to do the
# redirected stacks:show, so pass follow_redirects=False
resp = self.client.get('/stacks/%s' % stack_id,
follow_redirects=False)
# redirected stacks:show, so pass redirect=False
resp = self.client.get('/stacks/%s' % stack_id, redirect=False)
location = resp.headers.get('location')
path = self.client.strip_endpoint(location)
return path[len('/stacks/'):]