From 44e65a8516f53f2f5fe86ea71afefea24d59561d Mon Sep 17 00:00:00 2001 From: Steve Baker Date: Tue, 13 Aug 2013 09:25:03 +1200 Subject: [PATCH] Derive keystone_ec2_uri from auth_uri ec2token auth_uri must be correctly configured for heat to work. The /ec2tokens path is not an endpoint in its own right, it is part of the keystone v2.0 API. The keystone_ec2_uri configuration parameter was only used for ec2 style credentials validation in the ec2token middleware. It might have also propagated all the way into the user_creds table to be stored for each stack were it not for this chain of failures (removed in this commit): - X-Auth-EC2_URL header is set in ec2token, but header X-Auth-EC2-Url is read by RequestContext - RequestContext stores the ec2 uri in aws_auth_uri, but UserCreds expects aws_auth_url Change-Id: I9908e17bed33fdc64d058a6d6db7b29f9c8d53d6 --- etc/heat/heat-api-cfn.conf | 1 - etc/heat/heat-api-cloudwatch.conf | 1 - etc/heat/heat.conf.sample | 3 --- heat/api/aws/ec2token.py | 14 +++++++----- heat/common/context.py | 7 +----- heat/tests/test_api_ec2token.py | 37 +++++++++++++------------------ 6 files changed, 25 insertions(+), 38 deletions(-) diff --git a/etc/heat/heat-api-cfn.conf b/etc/heat/heat-api-cfn.conf index 35d0a21e..17fb3fa1 100644 --- a/etc/heat/heat-api-cfn.conf +++ b/etc/heat/heat-api-cfn.conf @@ -47,4 +47,3 @@ admin_password = verybadpass [ec2authtoken] auth_uri = http://127.0.0.1:5000/v2.0 -keystone_ec2_uri = http://localhost:5000/v2.0/ec2tokens diff --git a/etc/heat/heat-api-cloudwatch.conf b/etc/heat/heat-api-cloudwatch.conf index b95b016d..5c3f4b66 100644 --- a/etc/heat/heat-api-cloudwatch.conf +++ b/etc/heat/heat-api-cloudwatch.conf @@ -45,4 +45,3 @@ admin_password = verybadpass [ec2authtoken] auth_uri = http://127.0.0.1:5000/v2.0 -keystone_ec2_uri = http://localhost:5000/v2.0/ec2tokens diff --git a/etc/heat/heat.conf.sample b/etc/heat/heat.conf.sample index fd4baf29..dc93e1c1 100644 --- a/etc/heat/heat.conf.sample +++ b/etc/heat/heat.conf.sample @@ -498,9 +498,6 @@ # Authentication Endpoint URI (string value) #auth_uri= -# Keystone EC2 Service Endpoint URI (string value) -#keystone_ec2_uri= - [matchmaker_redis] diff --git a/heat/api/aws/ec2token.py b/heat/api/aws/ec2token.py index 996fb006..10089c41 100644 --- a/heat/api/aws/ec2token.py +++ b/heat/api/aws/ec2token.py @@ -36,10 +36,7 @@ logger = logging.getLogger(__name__) opts = [ cfg.StrOpt('auth_uri', default=None, - help=_("Authentication Endpoint URI")), - cfg.StrOpt('keystone_ec2_uri', - default=None, - help=_("Keystone EC2 Service Endpoint URI")) + help=_("Authentication Endpoint URI")) ] cfg.CONF.register_opts(opts, group='ec2authtoken') @@ -58,6 +55,12 @@ class EC2Token(wsgi.Middleware): else: return cfg.CONF.ec2authtoken[name] + def _conf_get_keystone_ec2_uri(self): + auth_uri = self._conf_get('auth_uri') + if auth_uri.endswith('/'): + return '%sec2tokens' % auth_uri + return '%s/ec2tokens' % auth_uri + def _get_signature(self, req): """ Extract the signature from the request, this can be a get/post @@ -145,7 +148,7 @@ class EC2Token(wsgi.Middleware): # for httplib and urlparse # pylint: disable-msg=E1101 - keystone_ec2_uri = self._conf_get('keystone_ec2_uri') + keystone_ec2_uri = self._conf_get_keystone_ec2_uri() logger.info('Authenticating with %s' % keystone_ec2_uri) o = urlparse.urlparse(keystone_ec2_uri) if o.scheme == 'http': @@ -190,7 +193,6 @@ class EC2Token(wsgi.Middleware): req.headers['X-Tenant-Name'] = tenant req.headers['X-Tenant-Id'] = tenant_id req.headers['X-Auth-URL'] = self._conf_get('auth_uri') - req.headers['X-Auth-EC2_URL'] = keystone_ec2_uri metadata = result['access'].get('metadata', {}) roles = metadata.get('roles', []) diff --git a/heat/common/context.py b/heat/common/context.py index caa8f0b5..b3711e87 100644 --- a/heat/common/context.py +++ b/heat/common/context.py @@ -35,7 +35,7 @@ class RequestContext(context.RequestContext): """ def __init__(self, auth_token=None, username=None, password=None, - aws_creds=None, aws_auth_uri=None, tenant=None, + aws_creds=None, tenant=None, tenant_id=None, auth_url=None, roles=None, is_admin=False, read_only=False, show_deleted=False, owner_is_tenant=True, overwrite=True, **kwargs): @@ -56,7 +56,6 @@ class RequestContext(context.RequestContext): self.username = username self.password = password self.aws_creds = aws_creds - self.aws_auth_uri = aws_auth_uri self.tenant_id = tenant_id self.auth_url = auth_url self.roles = roles or [] @@ -79,7 +78,6 @@ class RequestContext(context.RequestContext): 'username': self.user, 'password': self.password, 'aws_creds': self.aws_creds, - 'aws_auth_uri': self.aws_auth_uri, 'tenant': self.tenant, 'tenant_id': self.tenant_id, 'auth_url': self.auth_url, @@ -157,14 +155,12 @@ class ContextMiddleware(wsgi.Middleware): username = None password = None aws_creds = None - aws_auth_uri = None if headers.get('X-Auth-User') is not None: username = headers.get('X-Auth-User') password = headers.get('X-Auth-Key') elif headers.get('X-Auth-EC2-Creds') is not None: aws_creds = headers.get('X-Auth-EC2-Creds') - aws_auth_uri = headers.get('X-Auth-EC2-Url') token = headers.get('X-Auth-Token') tenant = headers.get('X-Tenant-Name') @@ -180,7 +176,6 @@ class ContextMiddleware(wsgi.Middleware): req.context = self.make_context(auth_token=token, tenant=tenant, tenant_id=tenant_id, aws_creds=aws_creds, - aws_auth_uri=aws_auth_uri, username=username, password=password, auth_url=auth_url, roles=roles, diff --git a/heat/tests/test_api_ec2token.py b/heat/tests/test_api_ec2token.py index 373b18f3..f0f28d49 100644 --- a/heat/tests/test_api_ec2token.py +++ b/heat/tests/test_api_ec2token.py @@ -37,18 +37,19 @@ class Ec2TokenTest(HeatTestCase): return req def test_conf_get_paste(self): - dummy_conf = {'auth_uri': 'abc', - 'keystone_ec2_uri': 'xyz'} + dummy_conf = {'auth_uri': 'http://192.0.2.9/v2.0'} ec2 = ec2token.EC2Token(app=None, conf=dummy_conf) - self.assertEqual(ec2._conf_get('auth_uri'), 'abc') - self.assertEqual(ec2._conf_get('keystone_ec2_uri'), 'xyz') + self.assertEqual(ec2._conf_get('auth_uri'), 'http://192.0.2.9/v2.0') + self.assertEqual(ec2._conf_get_keystone_ec2_uri(), + 'http://192.0.2.9/v2.0/ec2tokens') def test_conf_get_opts(self): - cfg.CONF.set_default('auth_uri', 'abc', group='ec2authtoken') - cfg.CONF.set_default('keystone_ec2_uri', 'xyz', group='ec2authtoken') + cfg.CONF.set_default('auth_uri', 'http://192.0.2.9/v2.0/', + group='ec2authtoken') ec2 = ec2token.EC2Token(app=None, conf={}) - self.assertEqual(ec2._conf_get('auth_uri'), 'abc') - self.assertEqual(ec2._conf_get('keystone_ec2_uri'), 'xyz') + self.assertEqual(ec2._conf_get('auth_uri'), 'http://192.0.2.9/v2.0/') + self.assertEqual(ec2._conf_get_keystone_ec2_uri(), + 'http://192.0.2.9/v2.0/ec2tokens') def test_get_signature_param_old(self): params = {'Signature': 'foo'} @@ -196,7 +197,7 @@ class Ec2TokenTest(HeatTestCase): "path": "/v1", "body_hash": body_hash}}) req_headers = {'Content-Type': 'application/json'} - req_path = '/foo' + req_path = '/v2.0/ec2tokens' httplib.HTTPConnection.request('POST', req_path, body=req_creds, headers=req_headers).AndReturn(None) @@ -208,8 +209,7 @@ class Ec2TokenTest(HeatTestCase): httplib.HTTPConnection.close().AndReturn(None) def test_call_ok(self): - dummy_conf = {'auth_uri': 'http://123:5000/foo', - 'keystone_ec2_uri': 'http://456:5000/foo'} + dummy_conf = {'auth_uri': 'http://123:5000/v2.0'} ec2 = ec2token.EC2Token(app='woot', conf=dummy_conf) auth_str = ('Authorization: foo Credential=foo/bar, ' @@ -234,8 +234,7 @@ class Ec2TokenTest(HeatTestCase): self.m.VerifyAll() def test_call_ok_roles(self): - dummy_conf = {'auth_uri': 'http://123:5000/foo', - 'keystone_ec2_uri': 'http://456:5000/foo'} + dummy_conf = {'auth_uri': 'http://123:5000/v2.0'} ec2 = ec2token.EC2Token(app='woot', conf=dummy_conf) auth_str = ('Authorization: foo Credential=foo/bar, ' @@ -262,8 +261,7 @@ class Ec2TokenTest(HeatTestCase): self.m.VerifyAll() def test_call_err_tokenid(self): - dummy_conf = {'auth_uri': 'http://123:5000/foo', - 'keystone_ec2_uri': 'http://456:5000/foo'} + dummy_conf = {'auth_uri': 'http://123:5000/v2.0/'} ec2 = ec2token.EC2Token(app='woot', conf=dummy_conf) auth_str = ('Authorization: foo Credential=foo/bar, ' @@ -286,8 +284,7 @@ class Ec2TokenTest(HeatTestCase): self.m.VerifyAll() def test_call_err_signature(self): - dummy_conf = {'auth_uri': 'http://123:5000/foo', - 'keystone_ec2_uri': 'http://456:5000/foo'} + dummy_conf = {'auth_uri': 'http://123:5000/v2.0'} ec2 = ec2token.EC2Token(app='woot', conf=dummy_conf) auth_str = ('Authorization: foo Credential=foo/bar, ' @@ -310,8 +307,7 @@ class Ec2TokenTest(HeatTestCase): self.m.VerifyAll() def test_call_err_denied(self): - dummy_conf = {'auth_uri': 'http://123:5000/foo', - 'keystone_ec2_uri': 'http://456:5000/foo'} + dummy_conf = {'auth_uri': 'http://123:5000/v2.0'} ec2 = ec2token.EC2Token(app='woot', conf=dummy_conf) auth_str = ('Authorization: foo Credential=foo/bar, ' @@ -333,8 +329,7 @@ class Ec2TokenTest(HeatTestCase): self.m.VerifyAll() def test_call_ok_v2(self): - dummy_conf = {'auth_uri': 'http://123:5000/foo', - 'keystone_ec2_uri': 'http://456:5000/foo'} + dummy_conf = {'auth_uri': 'http://123:5000/v2.0'} ec2 = ec2token.EC2Token(app='woot', conf=dummy_conf) params = {'AWSAccessKeyId': 'foo', 'Signature': 'xyz'} req_env = {'SERVER_NAME': 'heat', -- 2.45.2