# vim: tabstop=4 shiftwidth=4 softtabstop=4 # # 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. '''Implementation of SQLAlchemy backend.''' from sqlalchemy.orm.session import Session from heat.common import crypt from heat.common import exception from heat.db.sqlalchemy import models from heat.db.sqlalchemy.session import get_session def model_query(context, *args): session = _session(context) query = session.query(*args) return query def _session(context): return (context and context.session) or get_session() def raw_template_get(context, template_id): result = model_query(context, models.RawTemplate).get(template_id) if not result: raise exception.NotFound('raw template with id %s not found' % template_id) return result def raw_template_get_all(context): results = model_query(context, models.RawTemplate).all() if not results: raise exception.NotFound('no raw templates were found') return results def raw_template_create(context, values): raw_template_ref = models.RawTemplate() raw_template_ref.update(values) raw_template_ref.save(_session(context)) return raw_template_ref def resource_get(context, resource_id): result = model_query(context, models.Resource).get(resource_id) if not result: raise exception.NotFound("resource with id %s not found" % resource_id) return result def resource_get_by_name_and_stack(context, resource_name, stack_id): result = model_query(context, models.Resource).\ filter_by(name=resource_name).\ filter_by(stack_id=stack_id).first() return result def resource_get_by_physical_resource_id(context, physical_resource_id): results = (model_query(context, models.Resource) .filter_by(nova_instance=physical_resource_id) .all()) for result in results: if context is None or result.stack.tenant == context.tenant_id: return result return None def resource_get_all(context): results = model_query(context, models.Resource).all() if not results: raise exception.NotFound('no resources were found') return results def resource_create(context, values): resource_ref = models.Resource() resource_ref.update(values) resource_ref.save(_session(context)) return resource_ref def resource_get_all_by_stack(context, stack_id): results = model_query(context, models.Resource).\ filter_by(stack_id=stack_id).all() if not results: raise exception.NotFound("no resources for stack_id %s were found" % stack_id) return results def stack_get_by_name(context, stack_name, owner_id=None): query = model_query(context, models.Stack).\ filter_by(tenant=context.tenant_id).\ filter_by(name=stack_name).\ filter_by(owner_id=owner_id) return query.first() def stack_get(context, stack_id, admin=False): result = model_query(context, models.Stack).get(stack_id) # If the admin flag is True, we allow retrieval of a specific # stack without the tenant scoping if admin: return result if (result is not None and context is not None and result.tenant != context.tenant_id): return None return result def stack_get_all(context): results = model_query(context, models.Stack).\ filter_by(owner_id=None).all() return results def stack_get_all_by_tenant(context): results = model_query(context, models.Stack).\ filter_by(owner_id=None).\ filter_by(tenant=context.tenant_id).all() return results def stack_create(context, values): stack_ref = models.Stack() stack_ref.update(values) stack_ref.save(_session(context)) return stack_ref def stack_update(context, stack_id, values): stack = stack_get(context, stack_id) if not stack: raise exception.NotFound('Attempt to update a stack with id: %s %s' % (stack_id, 'that does not exist')) old_template_id = stack.raw_template_id stack.update(values) stack.save(_session(context)) # When the raw_template ID changes, we delete the old template # after storing the new template ID if stack.raw_template_id != old_template_id: session = Session.object_session(stack) rt = raw_template_get(context, old_template_id) session.delete(rt) session.flush() def stack_delete(context, stack_id): s = stack_get(context, stack_id) if not s: raise exception.NotFound('Attempt to delete a stack with id: %s %s' % (stack_id, 'that does not exist')) session = Session.object_session(s) for e in s.events: session.delete(e) for r in s.resources: session.delete(r) rt = s.raw_template uc = s.user_creds session.delete(s) session.delete(rt) session.delete(uc) session.flush() def user_creds_create(context): values = context.to_dict() user_creds_ref = models.UserCreds() user_creds_ref.update(values) user_creds_ref.password = crypt.encrypt(values['password']) user_creds_ref.aws_creds = crypt.encrypt(values['aws_creds']) user_creds_ref.save(_session(context)) return user_creds_ref def user_creds_get(user_creds_id): db_result = model_query(None, models.UserCreds).get(user_creds_id) # Return a dict copy of db results, do not decrypt details into db_result # or it can be committed back to the DB in decrypted form result = dict(db_result) result['password'] = crypt.decrypt(result['password']) result['aws_creds'] = crypt.decrypt(result['aws_creds']) return result def event_get(context, event_id): result = model_query(context, models.Event).get(event_id) return result def event_get_all(context): results = model_query(context, models.Event).all() return results def event_get_all_by_tenant(context): stacks = model_query(context, models.Stack).\ filter_by(tenant=context.tenant_id).all() results = [] for stack in stacks: results.extend(model_query(context, models.Event). filter_by(stack_id=stack.id).all()) return results def event_get_all_by_stack(context, stack_id): results = model_query(context, models.Event).\ filter_by(stack_id=stack_id).all() return results def event_create(context, values): event_ref = models.Event() event_ref.update(values) event_ref.save(_session(context)) return event_ref def watch_rule_get(context, watch_rule_id): result = model_query(context, models.WatchRule).\ filter_by(id=watch_rule_id).first() return result def watch_rule_get_by_name(context, watch_rule_name): result = model_query(context, models.WatchRule).\ filter_by(name=watch_rule_name).first() return result def watch_rule_get_all(context): results = model_query(context, models.WatchRule).all() return results def watch_rule_get_all_by_stack(context, stack_id): results = model_query(context, models.WatchRule).\ filter_by(stack_id=stack_id).all() return results def watch_rule_create(context, values): obj_ref = models.WatchRule() obj_ref.update(values) obj_ref.save(_session(context)) return obj_ref def watch_rule_update(context, watch_id, values): wr = watch_rule_get(context, watch_id) if not wr: raise exception.NotFound('Attempt to update a watch with id: %s %s' % (watch_id, 'that does not exist')) wr.update(values) wr.save(_session(context)) def watch_rule_delete(context, watch_id): wr = watch_rule_get(context, watch_id) if not wr: raise exception.NotFound('Attempt to delete watch_rule: %s %s' % (watch_id, 'that does not exist')) session = Session.object_session(wr) for d in wr.watch_data: session.delete(d) session.delete(wr) session.flush() def watch_data_create(context, values): obj_ref = models.WatchData() obj_ref.update(values) obj_ref.save(_session(context)) return obj_ref def watch_data_get_all(context): results = model_query(context, models.WatchData).all() return results def watch_data_delete(context, watch_name): ds = model_query(context, models.WatchRule).\ filter_by(name=watch_name).all() if not ds: raise exception.NotFound('Attempt to delete watch_data: %s %s' % (watch_name, 'that does not exist')) session = Session.object_session(ds) for d in ds: session.delete(d) session.flush()