Add --include-pass option for grizzly backwards compat

Set X-Auth-User, X-Auth-Key on all stack commands to allow the
latest python-heatclient to work on grizzly heat.

Partial-Bug:1250731

Change-Id: I29d4785cf3520e809252b5aeab25cf471a88cde8
This commit is contained in:
chenhaiq 2013-11-13 17:11:02 +08:00 committed by Steve Baker
parent fa084b50fa
commit 6f3e0842e4
3 changed files with 96 additions and 3 deletions

View File

@ -53,6 +53,7 @@ class HTTPClient(object):
self.username = kwargs.get('username')
self.password = kwargs.get('password')
self.region_name = kwargs.get('region_name')
self.include_pass = kwargs.get('include_pass')
self.connection_params = self.get_connection_params(endpoint, **kwargs)
@staticmethod
@ -137,6 +138,8 @@ class HTTPClient(object):
kwargs['headers'].setdefault('X-Auth-Url', self.auth_url)
if self.region_name:
kwargs['headers'].setdefault('X-Region-Name', self.region_name)
if self.include_pass and not 'X-Auth-Key' in kwargs['headers']:
kwargs['headers'].update(self.credentials_headers())
self.log_curl_request(method, url, kwargs)
conn = self.get_connection()
@ -160,7 +163,15 @@ class HTTPClient(object):
body_str = ''.join([chunk for chunk in body_iter])
self.log_http_response(resp, body_str)
if 400 <= resp.status < 600:
if not 'X-Auth-Key' in kwargs['headers'] and \
(resp.status == 401 or
(resp.status == 500 and "(HTTP 401)" in body_str)):
raise exc.HTTPUnauthorized("Authentication failed. Please try"
" again with option "
"--include-password or export "
"HEAT_INCLUDE_PASSWORD=1\n%s"
% body_str)
elif 400 <= resp.status < 600:
raise exc.from_response(resp, body_str)
elif resp.status in (301, 302, 305):
# Redirected. Reissue the request to the new location.

View File

@ -176,6 +176,11 @@ class HeatShell(object):
parser.add_argument('--os_endpoint_type',
help=argparse.SUPPRESS)
parser.add_argument('--include-password',
default=bool(utils.env('HEAT_INCLUDE_PASSWORD')),
action='store_true',
help='Send os-username and os-password to heat')
return parser
def get_subcommand_parser(self, version):
@ -328,7 +333,8 @@ class HeatShell(object):
'auth_url': args.os_auth_url,
'service_type': args.os_service_type,
'endpoint_type': args.os_endpoint_type,
'insecure': args.insecure
'insecure': args.insecure,
'include_pass': args.include_password
}
endpoint = args.heat_url
@ -346,7 +352,8 @@ class HeatShell(object):
'key_file': args.key_file,
'username': args.os_username,
'password': args.os_password,
'endpoint_type': args.os_endpoint_type
'endpoint_type': args.os_endpoint_type,
'include_pass': args.include_password
}
if args.os_region_name:

View File

@ -100,6 +100,81 @@ class HttpClientTest(testtools.TestCase):
self.assertEqual(resp.status, 200)
self.m.VerifyAll()
def test_include_pass(self):
# Record a 200
fake200 = fakes.FakeHTTPResponse(
200, 'OK',
{'content-type': 'application/octet-stream'},
'')
# no token or credentials
mock_conn = http.httplib.HTTPConnection('example.com', 8004,
timeout=600.0)
mock_conn.request('GET', '/',
headers={'Content-Type': 'application/octet-stream',
'User-Agent': 'python-heatclient'})
mock_conn.getresponse().AndReturn(fake200)
# credentials
mock_conn = http.httplib.HTTPConnection('example.com', 8004,
timeout=600.0)
mock_conn.request('GET', '/',
headers={'Content-Type': 'application/octet-stream',
'User-Agent': 'python-heatclient',
'X-Auth-Key': 'pass',
'X-Auth-User': 'user'})
mock_conn.getresponse().AndReturn(fake200)
# token suppresses credentials
mock_conn = http.httplib.HTTPConnection('example.com', 8004,
timeout=600.0)
mock_conn.request('GET', '/',
headers={'Content-Type': 'application/octet-stream',
'User-Agent': 'python-heatclient',
'X-Auth-Token': 'abcd1234',
'X-Auth-Key': 'pass',
'X-Auth-User': 'user'})
mock_conn.getresponse().AndReturn(fake200)
# Replay, create client, assert
self.m.ReplayAll()
client = http.HTTPClient('http://example.com:8004')
resp, body = client.raw_request('GET', '')
self.assertEqual(200, resp.status)
client.username = 'user'
client.password = 'pass'
client.include_pass = True
resp, body = client.raw_request('GET', '')
self.assertEqual(200, resp.status)
client.auth_token = 'abcd1234'
resp, body = client.raw_request('GET', '')
self.assertEqual(200, resp.status)
self.m.VerifyAll()
def test_not_include_pass(self):
# Record a 200
fake500 = fakes.FakeHTTPResponse(
500, 'ERROR',
{'content-type': 'application/octet-stream'},
'(HTTP 401)')
# no token or credentials
mock_conn = http.httplib.HTTPConnection('example.com', 8004,
timeout=600.0)
mock_conn.request('GET', '/',
headers={'Content-Type': 'application/octet-stream',
'User-Agent': 'python-heatclient'})
mock_conn.getresponse().AndReturn(fake500)
# Replay, create client, assert
self.m.ReplayAll()
client = http.HTTPClient('http://example.com:8004')
e = self.assertRaises(exc.HTTPUnauthorized,
client.raw_request, 'GET', '')
self.assertIn('include-password', str(e))
def test_region_name(self):
# Record a 200
fake200 = fakes.FakeHTTPResponse(