From a521e72a8b576222e19354e1bf45b49bc6bf5689 Mon Sep 17 00:00:00 2001 From: ShaoHe Feng Date: Wed, 11 Mar 2015 21:18:10 +0800 Subject: [PATCH] Versioned objects - UserCreds implementation for versioned objects. This contains UserCreds Co-Authored-By: Michal Jastrzebski (inc0) Co-Authored-By: Grzegorz Grasza Change-Id: Ibae5504060d2c714225cd8b735b430c7da52e0fa --- heat/engine/stack.py | 13 +++--- heat/objects/user_creds.py | 73 +++++++++++++++++++++++++++++++++ heat/tests/test_stack.py | 17 ++++---- heat/tests/test_stack_delete.py | 19 +++++---- 4 files changed, 100 insertions(+), 22 deletions(-) create mode 100644 heat/objects/user_creds.py diff --git a/heat/engine/stack.py b/heat/engine/stack.py index 9620a7a19..d36720477 100755 --- a/heat/engine/stack.py +++ b/heat/engine/stack.py @@ -43,6 +43,7 @@ from heat.engine import template as tmpl from heat.engine import update from heat.objects import resource as resource_objects from heat.objects import stack as stack_object +from heat.objects import user_creds as ucreds_object from heat.rpc import api as rpc_api cfg.CONF.import_opt('error_wait_time', 'heat.common.config') @@ -171,10 +172,11 @@ class Stack(collections.Mapping): def stored_context(self): if self.user_creds_id: - creds = db_api.user_creds_get(self.user_creds_id) + creds_obj = ucreds_object.UserCreds.get_by_id(self.user_creds_id) # Maintain request_id from self.context so we retain traceability # in situations where servicing a request requires switching from # the request context to the stored context + creds = creds_obj.obj_to_primitive()["versioned_object.data"] creds['request_id'] = self.context.request_id # We don't store roles in the user_creds table, so disable the # policy check for admin by setting is_admin=False. @@ -371,9 +373,9 @@ class Stack(collections.Mapping): if cfg.CONF.deferred_auth_method == 'trusts': keystone = self.clients.client('keystone') trust_ctx = keystone.create_trust_context() - new_creds = db_api.user_creds_create(trust_ctx) + new_creds = ucreds_object.UserCreds.create(trust_ctx) else: - new_creds = db_api.user_creds_create(self.context) + new_creds = ucreds_object.UserCreds.create(self.context) s['user_creds_id'] = new_creds.id self.user_creds_id = new_creds.id @@ -927,7 +929,7 @@ class Stack(collections.Mapping): # Ignore this error instead of blocking stack deletion. user_creds = None try: - user_creds = db_api.user_creds_get(self.user_creds_id) + user_creds = ucreds_object.UserCreds.get_by_id(self.user_creds_id) except exception.Error as err: LOG.exception(err) pass @@ -968,7 +970,8 @@ class Stack(collections.Mapping): # Delete the stored credentials try: - db_api.user_creds_delete(self.context, self.user_creds_id) + ucreds_object.UserCreds.delete(self.context, + self.user_creds_id) except exception.NotFound: LOG.info(_LI("Tried to delete user_creds that do not exist " "(stack=%(stack)s user_creds_id=%(uc)s)"), diff --git a/heat/objects/user_creds.py b/heat/objects/user_creds.py new file mode 100644 index 000000000..9b47c33fa --- /dev/null +++ b/heat/objects/user_creds.py @@ -0,0 +1,73 @@ +# Copyright 2014 Intel Corp. +# +# 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 +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. + + +""" +UserCreds object +""" + + +from oslo_versionedobjects import base +from oslo_versionedobjects import fields + +from heat.db import api as db_api + + +@base.VersionedObjectRegistry.register +class UserCreds(base.VersionedObject, + base.VersionedObjectDictCompat, + base.ComparableVersionedObject): + fields = { + 'id': fields.StringField(), + 'created_at': fields.DateTimeField(read_only=True), + 'updated_at': fields.DateTimeField(nullable=True), + 'username': fields.StringField(nullable=True), + 'password': fields.StringField(nullable=True), + 'tenant': fields.StringField(nullable=True), + 'tenant_id': fields.StringField(nullable=True), + 'trustor_user_id': fields.StringField(nullable=True), + 'trust_id': fields.StringField(nullable=True), + 'region_name': fields.StringField(nullable=True), + 'auth_url': fields.StringField(nullable=True), + 'decrypt_method': fields.StringField(nullable=True) + } + + @staticmethod + def _from_db_object(ucreds, db_ucreds, context=None): + if db_ucreds is None: + return db_ucreds + ucreds._context = context + for field in ucreds.fields: + # TODO(Shao HE Feng), now the db layer delete the decrypt_method + # field, just skip it here. and will add an encrypted_field later. + if field == "decrypt_method": + continue + ucreds[field] = db_ucreds[field] + ucreds.obj_reset_changes() + return ucreds + + @classmethod + def create(cls, context): + user_creds_db = db_api.user_creds_create(context) + return cls._from_db_object(cls(), user_creds_db) + + @classmethod + def delete(cls, context, user_creds_id): + return db_api.user_creds_delete(context, user_creds_id) + + @classmethod + def get_by_id(cls, context_id): + user_creds_db = db_api.user_creds_get(context_id) + user_creds = cls._from_db_object(cls(), user_creds_db) + return user_creds diff --git a/heat/tests/test_stack.py b/heat/tests/test_stack.py index 02835d6ed..b1ae69995 100644 --- a/heat/tests/test_stack.py +++ b/heat/tests/test_stack.py @@ -33,6 +33,7 @@ from heat.engine import scheduler from heat.engine import stack from heat.engine import template from heat.objects import stack as stack_object +from heat.objects import user_creds as ucreds_object from heat.tests import common from heat.tests import fakes from heat.tests import generic_resource as generic_rsrc @@ -1092,7 +1093,7 @@ class StackTest(common.HeatTestCase): ctx_init = utils.dummy_context(user='my_user', password='my_pass') ctx_init.request_id = self.ctx.request_id - creds = db_api.user_creds_create(ctx_init) + creds = ucreds_object.UserCreds.create(ctx_init) self.stack = stack.Stack(self.ctx, 'creds_init', self.tmpl, user_creds_id=creds.id) self.stack.store() @@ -1114,7 +1115,7 @@ class StackTest(common.HeatTestCase): self.assertIsNotNone(user_creds_id) # should've stored the username/password in the context - user_creds = db_api.user_creds_get(user_creds_id) + user_creds = ucreds_object.UserCreds.get_by_id(user_creds_id) self.assertEqual(self.ctx.username, user_creds.get('username')) self.assertEqual(self.ctx.password, user_creds.get('password')) self.assertIsNone(user_creds.get('trust_id')) @@ -1152,7 +1153,7 @@ class StackTest(common.HeatTestCase): # should've stored the trust_id and trustor_user_id returned from # FakeKeystoneClient.create_trust_context, username/password should # not have been stored - user_creds = db_api.user_creds_get(user_creds_id) + user_creds = ucreds_object.UserCreds.get_by_id(user_creds_id) self.assertIsNone(user_creds.get('username')) self.assertIsNone(user_creds.get('password')) self.assertEqual('atrust', user_creds.get('trust_id')) @@ -1173,7 +1174,7 @@ class StackTest(common.HeatTestCase): ctx_init = utils.dummy_context(user='my_user', password='my_pass') ctx_init.request_id = self.ctx.request_id - creds = db_api.user_creds_create(ctx_init) + creds = ucreds_object.UserCreds.create(ctx_init) self.stack = stack.Stack(self.ctx, 'creds_init', self.tmpl, user_creds_id=creds.id) self.stack.store() @@ -1218,7 +1219,7 @@ class StackTest(common.HeatTestCase): ctx_init = utils.dummy_context(user='mystored_user', password='mystored_pass') ctx_init.request_id = self.ctx.request_id - creds = db_api.user_creds_create(ctx_init) + creds = ucreds_object.UserCreds.create(ctx_init) self.stack = stack.Stack(self.ctx, 'creds_store1', self.tmpl, user_creds_id=creds.id, use_stored_context=False) @@ -1231,7 +1232,7 @@ class StackTest(common.HeatTestCase): ctx_init = utils.dummy_context(user='mystored_user', password='mystored_pass') ctx_init.request_id = self.ctx.request_id - creds = db_api.user_creds_create(ctx_init) + creds = ucreds_object.UserCreds.create(ctx_init) self.stack = stack.Stack(self.ctx, 'creds_store2', self.tmpl, user_creds_id=creds.id, use_stored_context=True) @@ -1245,7 +1246,7 @@ class StackTest(common.HeatTestCase): ctx_init = utils.dummy_context(user='mystored_user', password='mystored_pass') ctx_init.request_id = self.ctx.request_id - creds = db_api.user_creds_create(ctx_init) + creds = ucreds_object.UserCreds.create(ctx_init) self.stack = stack.Stack(self.ctx, 'creds_store3', self.tmpl, user_creds_id=creds.id) self.stack.store() @@ -1258,7 +1259,7 @@ class StackTest(common.HeatTestCase): ctx_init = utils.dummy_context(user='mystored_user', password='mystored_pass') ctx_init.request_id = self.ctx.request_id - creds = db_api.user_creds_create(ctx_init) + creds = ucreds_object.UserCreds.create(ctx_init) self.stack = stack.Stack(self.ctx, 'creds_store4', self.tmpl, user_creds_id=creds.id) self.stack.store() diff --git a/heat/tests/test_stack_delete.py b/heat/tests/test_stack_delete.py index 191dfcbec..de3191120 100644 --- a/heat/tests/test_stack_delete.py +++ b/heat/tests/test_stack_delete.py @@ -27,6 +27,7 @@ from heat.engine import resource from heat.engine import scheduler from heat.engine import stack from heat.engine import template +from heat.objects import user_creds as ucreds_object from heat.tests import common from heat.tests import fakes from heat.tests import generic_resource as generic_rsrc @@ -68,14 +69,14 @@ class StackTest(common.HeatTestCase): self.assertIsNotNone(db_s) self.assertIsNotNone(db_s.user_creds_id) user_creds_id = db_s.user_creds_id - db_creds = db_api.user_creds_get(db_s.user_creds_id) + db_creds = ucreds_object.UserCreds.get_by_id(db_s.user_creds_id) self.assertIsNotNone(db_creds) self.stack.delete() db_s = db_api.stack_get(self.ctx, stack_id) self.assertIsNone(db_s) - db_creds = db_api.user_creds_get(user_creds_id) + db_creds = ucreds_object.UserCreds.get_by_id(user_creds_id) self.assertIsNone(db_creds) del_db_s = db_api.stack_get(self.ctx, stack_id, show_deleted=True) self.assertIsNone(del_db_s.user_creds_id) @@ -96,16 +97,16 @@ class StackTest(common.HeatTestCase): self.assertIsNotNone(db_s) self.assertIsNotNone(db_s.user_creds_id) user_creds_id = db_s.user_creds_id - db_creds = db_api.user_creds_get(db_s.user_creds_id) + db_creds = ucreds_object.UserCreds.get_by_id(db_s.user_creds_id) self.assertIsNotNone(db_creds) - db_api.user_creds_delete(self.ctx, user_creds_id) + ucreds_object.UserCreds.delete(self.ctx, user_creds_id) self.stack.delete() db_s = db_api.stack_get(self.ctx, stack_id) self.assertIsNone(db_s) - db_creds = db_api.user_creds_get(user_creds_id) + db_creds = ucreds_object.UserCreds.get_by_id(user_creds_id) self.assertIsNone(db_creds) del_db_s = db_api.stack_get(self.ctx, stack_id, show_deleted=True) self.assertIsNone(del_db_s.user_creds_id) @@ -169,7 +170,7 @@ class StackTest(common.HeatTestCase): user_creds_id = db_s.user_creds_id self.assertIsNotNone(user_creds_id) - user_creds = db_api.user_creds_get(user_creds_id) + user_creds = ucreds_object.UserCreds.get_by_id(user_creds_id) self.assertEqual('thetrustor', user_creds.get('trustor_user_id')) self.stack.delete() @@ -203,7 +204,7 @@ class StackTest(common.HeatTestCase): user_creds_id = db_s.user_creds_id self.assertIsNotNone(user_creds_id) - user_creds = db_api.user_creds_get(user_creds_id) + user_creds = ucreds_object.UserCreds.get_by_id(user_creds_id) self.assertEqual('thetrustor', user_creds.get('trustor_user_id')) mock_kc.return_value = fakes.FakeKeystoneClient(user_id='nottrustor') @@ -260,14 +261,14 @@ class StackTest(common.HeatTestCase): self.assertIsNotNone(db_s) user_creds_id = db_s.user_creds_id self.assertIsNotNone(user_creds_id) - user_creds = db_api.user_creds_get(user_creds_id) + user_creds = ucreds_object.UserCreds.get_by_id(user_creds_id) self.assertIsNotNone(user_creds) self.stack.delete() db_s = db_api.stack_get(self.ctx, stack_id) self.assertIsNone(db_s) - user_creds = db_api.user_creds_get(user_creds_id) + user_creds = ucreds_object.UserCreds.get_by_id(user_creds_id) self.assertIsNotNone(user_creds) self.assertEqual((stack.Stack.DELETE, stack.Stack.COMPLETE), self.stack.state)