From: Steven Hardy Date: Fri, 19 Oct 2012 18:02:33 +0000 (+0100) Subject: heat engine : Rework auth.authenticate X-Git-Tag: 2014.1~1289 X-Git-Url: https://review.fuel-infra.org/gitweb?a=commitdiff_plain;h=13ec48afe3aa12804cf15ad02557b1949cd52cdc;p=openstack-build%2Fheat-build.git heat engine : Rework auth.authenticate engine.auth.authenticate is really creating a novaclient connection, so move this into Resource.nova Ref #268 Change-Id: I15d9c0537b3af9e65cd1ea5bd667bde0c89dc4c2 Signed-off-by: Steven Hardy --- diff --git a/heat/engine/auth.py b/heat/engine/auth.py index cffc566c..1b1a11c9 100644 --- a/heat/engine/auth.py +++ b/heat/engine/auth.py @@ -59,49 +59,3 @@ def decrypt(auth_info): cipher = AES.new(cfg.CONF.auth_encryption_key[:32], AES.MODE_CFB, iv) res = cipher.decrypt(auth[AES.block_size:]) return res - - -def authenticate(con, service_type='cloudformation', service_name='heat-cfn'): - """ Authenticate a user context. This authenticates either an - EC2 style key context or a keystone user/pass context. - - In the case of EC2 style authentication this will also set the - username in the context so we can use it to key in the database. - """ - - args = { - 'project_id': con.tenant, - 'auth_url': con.auth_url, - 'service_type': service_type, - 'service_name': service_name, - } - - if con.password is not None: - credentials = { - 'username': con.username, - 'api_key': con.password, - } - elif con.auth_token is not None: - credentials = { - 'username': con.service_user, - 'api_key': con.service_password, - 'proxy_token': con.auth_token, - 'proxy_tenant_id': con.tenant_id, - } - else: - logger.error("Authentication failed, no password or auth_token!") - return None - - args.update(credentials) - try: - # Workaround for issues with python-keyring, need no_cache=True - # ref https://bugs.launchpad.net/python-novaclient/+bug/1020238 - # TODO(shardy): May be able to remove when the bug above is fixed - nova = client.Client(no_cache=True, **args) - except TypeError: - # for compatibility with essex, which doesn't have no_cache=True - # TODO(shardy): remove when we no longer support essex - nova = client.Client(**args) - - nova.authenticate() - return nova diff --git a/heat/engine/resources.py b/heat/engine/resources.py index 1759e37f..2e5879af 100644 --- a/heat/engine/resources.py +++ b/heat/engine/resources.py @@ -231,10 +231,41 @@ class Resource(object): if service_type in self._nova: return self._nova[service_type] - self._nova[service_type] = auth.authenticate(self.context, - service_type=service_type, - service_name=None) - return self._nova[service_type] + con = self.context + args = { + 'project_id': con.tenant, + 'auth_url': con.auth_url, + 'service_type': service_type, + } + + if con.password is not None: + args['username'] = con.username + args['api_key'] = con.password + elif con.auth_token is not None: + args['username'] = con.service_user + args['api_key'] = con.service_password + args['proxy_token'] = con.auth_token + args['proxy_tenant_id'] = con.tenant_id + else: + logger.error("Nova connection failed, no password or auth_token!") + return None + + client = None + try: + # Workaround for issues with python-keyring, need no_cache=True + # ref https://bugs.launchpad.net/python-novaclient/+bug/1020238 + # TODO(shardy): May be able to remove when the bug above is fixed + client = nc.Client(no_cache=True, **args) + client.authenticate() + self._nova[service_type] = client + except TypeError: + # for compatibility with essex, which doesn't have no_cache=True + # TODO(shardy): remove when we no longer support essex + client = nc.Client(**args) + client.authenticate() + self._nova[service_type] = client + + return client def swift(self): if swiftclient_present == False: diff --git a/heat/tests/test_api_cfn_v1.py b/heat/tests/test_api_cfn_v1.py index 0e25b45c..e56f231f 100644 --- a/heat/tests/test_api_cfn_v1.py +++ b/heat/tests/test_api_cfn_v1.py @@ -27,7 +27,6 @@ import urlparse from heat.common import config from heat.common import context -from heat.engine import auth from heat.engine import identifier from heat.openstack.common import cfg from heat.openstack.common import rpc @@ -51,7 +50,6 @@ class StackControllerTest(unittest.TestCase): ctx.username = user self.m.StubOutWithMock(ctx, 'tenant_id') ctx.tenant_id = 't' - self.m.StubOutWithMock(auth, 'authenticate') return ctx def _dummy_GET_request(self, params={}): diff --git a/heat/tests/test_api_cloudwatch.py b/heat/tests/test_api_cloudwatch.py index 3e5fb7ac..1a6fa4b1 100644 --- a/heat/tests/test_api_cloudwatch.py +++ b/heat/tests/test_api_cloudwatch.py @@ -27,7 +27,6 @@ import urlparse from heat.common import config from heat.common import context -from heat.engine import auth from heat.openstack.common import cfg from heat.openstack.common import rpc import heat.openstack.common.rpc.common as rpc_common @@ -49,7 +48,6 @@ class WatchControllerTest(unittest.TestCase): ctx = context.get_admin_context() self.m.StubOutWithMock(ctx, 'username') ctx.username = user - self.m.StubOutWithMock(auth, 'authenticate') return ctx def _dummy_GET_request(self, params={}): diff --git a/heat/tests/test_api_openstack_v1.py b/heat/tests/test_api_openstack_v1.py index b5a52075..93034ee5 100644 --- a/heat/tests/test_api_openstack_v1.py +++ b/heat/tests/test_api_openstack_v1.py @@ -27,7 +27,6 @@ import webob.exc from heat.common import config from heat.common import context -from heat.engine import auth from heat.engine import identifier from heat.openstack.common import cfg from heat.openstack.common import rpc @@ -163,7 +162,6 @@ class StackControllerTest(unittest.TestCase): ctx.username = user self.m.StubOutWithMock(ctx, 'tenant_id') ctx.tenant_id = self.tenant - self.m.StubOutWithMock(auth, 'authenticate') return ctx def _environ(self, path): diff --git a/heat/tests/test_validate.py b/heat/tests/test_validate.py index 122f3dc4..4f64a5aa 100644 --- a/heat/tests/test_validate.py +++ b/heat/tests/test_validate.py @@ -228,8 +228,6 @@ class validateTest(unittest.TestCase): def test_validate_volumeattach_valid(self): t = json.loads(test_template_volumeattach % 'vdq') - self.m.StubOutWithMock(auth, 'authenticate') - auth.authenticate(None).AndReturn(True) stack = parser.Stack(None, 'test_stack', parser.Template(t)) self.m.StubOutWithMock(db_api, 'resource_get_by_name_and_stack') @@ -242,8 +240,6 @@ class validateTest(unittest.TestCase): def test_validate_volumeattach_invalid(self): t = json.loads(test_template_volumeattach % 'sda') - self.m.StubOutWithMock(auth, 'authenticate') - auth.authenticate(None).AndReturn(True) stack = parser.Stack(None, 'test_stack', parser.Template(t)) self.m.StubOutWithMock(db_api, 'resource_get_by_name_and_stack') @@ -258,8 +254,6 @@ class validateTest(unittest.TestCase): t = json.loads(test_template_ref % 'WikiDatabase') t['Parameters']['KeyName']['Value'] = 'test' params = {} - self.m.StubOutWithMock(auth, 'authenticate') - auth.authenticate(None).AndReturn(True) self.m.StubOutWithMock(instances.Instance, 'nova') instances.Instance.nova().AndReturn(self.fc) @@ -275,8 +269,6 @@ class validateTest(unittest.TestCase): t = json.loads(test_template_ref % 'WikiDatabasez') t['Parameters']['KeyName']['Value'] = 'test' params = {} - self.m.StubOutWithMock(auth, 'authenticate') - auth.authenticate(None).AndReturn(True) self.m.StubOutWithMock(instances.Instance, 'nova') instances.Instance.nova().AndReturn(self.fc) @@ -291,8 +283,6 @@ class validateTest(unittest.TestCase): t = json.loads(test_template_findinmap_valid) t['Parameters']['KeyName']['Value'] = 'test' params = {} - self.m.StubOutWithMock(auth, 'authenticate') - auth.authenticate(None).AndReturn(True) self.m.StubOutWithMock(instances.Instance, 'nova') instances.Instance.nova().AndReturn(self.fc) @@ -307,8 +297,6 @@ class validateTest(unittest.TestCase): t = json.loads(test_template_findinmap_invalid) t['Parameters']['KeyName']['Value'] = 'test' params = {} - self.m.StubOutWithMock(auth, 'authenticate') - auth.authenticate(None).AndReturn(True) self.m.StubOutWithMock(instances.Instance, 'nova') instances.Instance.nova().AndReturn(self.fc)