From e646e66728e5ca9f627c56137a40c74a195060a1 Mon Sep 17 00:00:00 2001 From: Ian Main Date: Wed, 25 Jul 2012 12:02:53 -0700 Subject: [PATCH] Change to per-tenant stacks. This patch switches from per-user stacks to per-tenant stacks. Change-Id: Ia7ac65033560bcff1db83d4d673945029e06ea6a Signed-off-by: Ian Main --- heat/db/api.py | 8 ++++---- heat/db/sqlalchemy/api.py | 14 ++++++------- .../migrate_repo/versions/011_stack_tenant.py | 20 +++++++++++++++++++ heat/db/sqlalchemy/models.py | 1 + heat/engine/manager.py | 4 ++-- heat/engine/parser.py | 1 + heat/tests/test_stacks.py | 16 +++++++++------ 7 files changed, 45 insertions(+), 19 deletions(-) create mode 100644 heat/db/sqlalchemy/migrate_repo/versions/011_stack_tenant.py diff --git a/heat/db/api.py b/heat/db/api.py index 62616c08..d67bd2e2 100644 --- a/heat/db/api.py +++ b/heat/db/api.py @@ -99,8 +99,8 @@ def stack_get_all(context): return IMPL.stack_get_all(context) -def stack_get_by_user(context): - return IMPL.stack_get_by_user(context) +def stack_get_by_tenant(context): + return IMPL.stack_get_by_tenant(context) def stack_create(context, values): @@ -131,8 +131,8 @@ def event_get_all(context): return IMPL.event_get_all(context) -def event_get_all_by_user(context): - return IMPL.event_get_all_by_user(context) +def event_get_all_by_tenant(context): + return IMPL.event_get_all_by_tenant(context) def event_get_all_by_stack(context, stack_id): diff --git a/heat/db/sqlalchemy/api.py b/heat/db/sqlalchemy/api.py index fd20af1e..7365dfd5 100644 --- a/heat/db/sqlalchemy/api.py +++ b/heat/db/sqlalchemy/api.py @@ -79,7 +79,7 @@ def resource_get_by_physical_resource_id(context, physical_resource_id): .filter_by(nova_instance=physical_resource_id) .first()) if (result is not None and context is not None and - result.stack.username != context.username): + result.stack.tenant != context.tenant): return None return result @@ -119,7 +119,7 @@ def stack_get_by_name(context, stack_name, owner_id=None): result = model_query(context, models.Stack).\ filter_by(name=stack_name).first() if (result is not None and context is not None and - result.username != context.username): + result.tenant != context.tenant): return None return result @@ -128,7 +128,7 @@ def stack_get(context, stack_id): result = model_query(context, models.Stack).get(stack_id) if (result is not None and context is not None and - result.username != context.username): + result.tenant != context.tenant): return None return result @@ -140,10 +140,10 @@ def stack_get_all(context): return results -def stack_get_by_user(context): +def stack_get_by_tenant(context): results = model_query(context, models.Stack).\ filter_by(owner_id=None).\ - filter_by(username=context.username).all() + filter_by(tenant=context.tenant).all() return results @@ -224,9 +224,9 @@ def event_get_all(context): return results -def event_get_all_by_user(context): +def event_get_all_by_tenant(context): stacks = model_query(context, models.Stack).\ - filter_by(username=context.username).all() + filter_by(tenant=context.tenant).all() results = [] for stack in stacks: results.extend(model_query(context, models.Event). diff --git a/heat/db/sqlalchemy/migrate_repo/versions/011_stack_tenant.py b/heat/db/sqlalchemy/migrate_repo/versions/011_stack_tenant.py new file mode 100644 index 00000000..70721c4b --- /dev/null +++ b/heat/db/sqlalchemy/migrate_repo/versions/011_stack_tenant.py @@ -0,0 +1,20 @@ +from sqlalchemy import * +from migrate import * + + +def upgrade(migrate_engine): + meta = MetaData(bind=migrate_engine) + + stack = Table('stack', meta, autoload=True) + + Column('tenant', String(length=256, convert_unicode=False, + assert_unicode=None, + unicode_error=None, + _warn_on_bytestring=False)).create(stack) + + +def downgrade(migrate_engine): + meta = MetaData() + meta.bind = migrate_engine + stack = Table('stack', meta, autoload=True) + stack.c.tenant.drop() diff --git a/heat/db/sqlalchemy/models.py b/heat/db/sqlalchemy/models.py index 63ec8ad9..4e70bdf4 100644 --- a/heat/db/sqlalchemy/models.py +++ b/heat/db/sqlalchemy/models.py @@ -151,6 +151,7 @@ class Stack(BASE, HeatBase): raw_template = relationship(RawTemplate, backref=backref('stack')) username = Column(String) + tenant = Column(String) status = Column('status', String) status_reason = Column('status_reason', String) parameters = Column('parameters', Json) diff --git a/heat/engine/manager.py b/heat/engine/manager.py index 239bf679..e86ee632 100644 --- a/heat/engine/manager.py +++ b/heat/engine/manager.py @@ -77,7 +77,7 @@ class EngineManager(manager.Manager): else: raise AttributeError('Unknown stack name') else: - stacks = db_api.stack_get_by_user(context) or [] + stacks = db_api.stack_get_by_tenant(context) or [] def format_stack_detail(s): stack = parser.Stack.load(context, s.id) @@ -253,7 +253,7 @@ class EngineManager(manager.Manager): events = db_api.event_get_all_by_stack(context, st.id) else: - events = db_api.event_get_all_by_user(context) + events = db_api.event_get_all_by_tenant(context) return {'events': [api.format_event(e) for e in events]} diff --git a/heat/engine/parser.py b/heat/engine/parser.py index b54d9693..283d2afc 100644 --- a/heat/engine/parser.py +++ b/heat/engine/parser.py @@ -308,6 +308,7 @@ class Stack(object): 'owner_id': owner and owner.id, 'user_creds_id': new_creds.id, 'username': self.context.username, + 'tenant': self.context.tenant, 'status': self.state, 'status_reason': self.state_description, 'timeout': self.timeout_mins, diff --git a/heat/tests/test_stacks.py b/heat/tests/test_stacks.py index ec813cb7..fa35fa45 100644 --- a/heat/tests/test_stacks.py +++ b/heat/tests/test_stacks.py @@ -39,10 +39,13 @@ templates_dir = os.path.normpath(os.path.join(tests_dir, 'templates')) -def create_context(mocks, user='stacks_test_user', ctx=None): +def create_context(mocks, user='stacks_test_user', + tenant='test_admin', ctx=None): ctx = ctx or context.get_admin_context() mocks.StubOutWithMock(ctx, 'username') + mocks.StubOutWithMock(ctx, 'tenant') ctx.username = user + ctx.tenant = tenant mocks.StubOutWithMock(auth, 'authenticate') return ctx @@ -100,7 +103,7 @@ class stackCreateTest(unittest.TestCase): self.assertNotEqual(stack.resources['WebServer'].ipaddress, '0.0.0.0') def test_wordpress_single_instance_stack_delete(self): - ctx = create_context(self.m, 'test_delete_user') + ctx = create_context(self.m, tenant='test_delete_tenant') stack = get_wordpress_stack('test_stack', ctx) setup_mocks(self.m, stack) self.m.ReplayAll() @@ -127,7 +130,8 @@ class stackManagerTest(unittest.TestCase): def setUpClass(cls): m = mox.Mox() cls.username = 'stack_manager_test_user' - ctx = create_context(m, cls.username) + cls.tenant = 'stack_manager_test_tenant' + ctx = create_context(m, cls.username, cls.tenant) cls.stack_name = 'manager_test_stack' stack = get_wordpress_stack(cls.stack_name, ctx) @@ -144,7 +148,7 @@ class stackManagerTest(unittest.TestCase): def tearDownClass(cls): cls = cls m = mox.Mox() - create_context(m, cls.username, ctx=cls.stack.context) + create_context(m, cls.username, cls.tenant, ctx=cls.stack.context) setup_mocks(m, cls.stack) m.ReplayAll() @@ -154,7 +158,7 @@ class stackManagerTest(unittest.TestCase): def setUp(self): self.m = mox.Mox() - self.ctx = create_context(self.m, self.username) + self.ctx = create_context(self.m, self.username, self.tenant) auth.authenticate(self.ctx).AndReturn(True) setup_mocks(self.m, self.stack) self.m.ReplayAll() @@ -217,7 +221,7 @@ class stackManagerTest(unittest.TestCase): def test_stack_describe_all_empty(self): self.tearDown() - self.username = 'stack_describe_all_empty_user' + self.tenant = 'stack_describe_all_empty_tenant' self.setUp() sl = self.man.show_stack(self.ctx, None, {}) -- 2.45.2