~ubuntu-branches/ubuntu/trusty/heat/trusty

« back to all changes in this revision

Viewing changes to heat/db/sqlalchemy/api.py

  • Committer: Package Import Robot
  • Author(s): Chuck Short, Chuck Short, Adam Gandelman
  • Date: 2013-09-08 21:51:19 UTC
  • mfrom: (1.1.4)
  • Revision ID: package-import@ubuntu.com-20130908215119-r939tu4aumqgdrkx
Tags: 2013.2~b3-0ubuntu1
[ Chuck Short ]
* New upstream release.
* debian/control: Add python-netaddr as build-dep.
* debian/heat-common.install: Remove heat-boto and associated man-page
* debian/heat-common.install: Remove heat-cfn and associated man-page
* debian/heat-common.install: Remove heat-watch and associated man-page
* debian/patches/fix-sqlalchemy-0.8.patch: Dropped

[ Adam Gandelman ]
* debian/patches/default-kombu.patch: Dropped.
* debian/patches/default-sqlite.patch: Refreshed.
* debian/*.install, rules: Install heat.conf.sample as common
  config file in heat-common. Drop other per-package configs, they
  are no longer used.
* debian/rules: Clean pbr .egg from build dir if it exists.

Show diffs side-by-side

added added

removed removed

Lines of Context:
14
14
#    under the License.
15
15
 
16
16
'''Implementation of SQLAlchemy backend.'''
 
17
from datetime import datetime
 
18
from datetime import timedelta
 
19
 
 
20
import sqlalchemy
17
21
from sqlalchemy.orm.session import Session
18
22
 
 
23
from heat.openstack.common.gettextutils import _
 
24
 
19
25
from heat.common import crypt
20
26
from heat.common import exception
21
27
from heat.db.sqlalchemy import models
 
28
from heat.db.sqlalchemy.session import get_engine
22
29
from heat.db.sqlalchemy.session import get_session
23
30
 
24
31
 
29
36
    return query
30
37
 
31
38
 
 
39
def soft_delete_aware_query(context, *args, **kwargs):
 
40
    """Stack query helper that accounts for context's `show_deleted` field.
 
41
 
 
42
    :param show_deleted: if present, overrides context's show_deleted field.
 
43
    """
 
44
 
 
45
    query = model_query(context, *args)
 
46
    show_deleted = kwargs.get('show_deleted')
 
47
 
 
48
    if not show_deleted:
 
49
        query = query.filter_by(deleted_at=None)
 
50
 
 
51
    return query
 
52
 
 
53
 
32
54
def _session(context):
33
55
    return (context and context.session) or get_session()
34
56
 
43
65
    return result
44
66
 
45
67
 
46
 
def raw_template_get_all(context):
47
 
    results = model_query(context, models.RawTemplate).all()
48
 
 
49
 
    if not results:
50
 
        raise exception.NotFound('no raw templates were found')
51
 
 
52
 
    return results
53
 
 
54
 
 
55
68
def raw_template_create(context, values):
56
69
    raw_template_ref = models.RawTemplate()
57
70
    raw_template_ref.update(values)
131
144
    return current
132
145
 
133
146
 
 
147
def resource_exchange_stacks(context, resource_id1, resource_id2):
 
148
    query = model_query(context, models.Resource)
 
149
    session = query.session
 
150
    session.begin()
 
151
 
 
152
    res1 = query.get(resource_id1)
 
153
    res2 = query.get(resource_id2)
 
154
 
 
155
    res1.stack, res2.stack = res2.stack, res1.stack
 
156
 
 
157
    session.commit()
 
158
 
 
159
 
 
160
def resource_data_delete(resource, key):
 
161
    result = resource_data_get_by_key(resource.context, resource.id, key)
 
162
    result.delete()
 
163
 
 
164
 
134
165
def resource_create(context, values):
135
166
    resource_ref = models.Resource()
136
167
    resource_ref.update(values)
150
181
 
151
182
 
152
183
def stack_get_by_name(context, stack_name, owner_id=None):
153
 
    query = model_query(context, models.Stack).\
 
184
    query = soft_delete_aware_query(context, models.Stack).\
154
185
        filter_by(tenant=context.tenant_id).\
155
186
        filter_by(name=stack_name).\
156
187
        filter_by(owner_id=owner_id)
158
189
    return query.first()
159
190
 
160
191
 
161
 
def stack_get(context, stack_id, admin=False):
 
192
def stack_get(context, stack_id, admin=False, show_deleted=False):
162
193
    result = model_query(context, models.Stack).get(stack_id)
163
194
 
 
195
    if result is None or result.deleted_at is not None and not show_deleted:
 
196
        return None
 
197
 
164
198
    # If the admin flag is True, we allow retrieval of a specific
165
199
    # stack without the tenant scoping
166
200
    if admin:
174
208
 
175
209
 
176
210
def stack_get_all(context):
177
 
    results = model_query(context, models.Stack).\
 
211
    results = soft_delete_aware_query(context, models.Stack).\
178
212
        filter_by(owner_id=None).all()
179
213
    return results
180
214
 
181
215
 
182
216
def stack_get_all_by_tenant(context):
183
 
    results = model_query(context, models.Stack).\
 
217
    results = soft_delete_aware_query(context, models.Stack).\
184
218
        filter_by(owner_id=None).\
185
219
        filter_by(tenant=context.tenant_id).all()
186
220
    return results
205
239
    stack.update(values)
206
240
    stack.save(_session(context))
207
241
 
208
 
    # When the raw_template ID changes, we delete the old template
209
 
    # after storing the new template ID
210
 
    if stack.raw_template_id != old_template_id:
211
 
        session = Session.object_session(stack)
212
 
        rt = raw_template_get(context, old_template_id)
213
 
        session.delete(rt)
214
 
        session.flush()
215
 
 
216
242
 
217
243
def stack_delete(context, stack_id):
218
244
    s = stack_get(context, stack_id)
222
248
 
223
249
    session = Session.object_session(s)
224
250
 
225
 
    for e in s.events:
226
 
        session.delete(e)
227
 
 
228
251
    for r in s.resources:
229
252
        session.delete(r)
230
253
 
231
 
    rt = s.raw_template
232
 
    uc = s.user_creds
233
 
 
234
 
    session.delete(s)
235
 
    session.delete(rt)
236
 
    session.delete(uc)
 
254
    s.soft_delete(session=session)
237
255
 
238
256
    session.flush()
239
257
 
241
259
def user_creds_create(context):
242
260
    values = context.to_dict()
243
261
    user_creds_ref = models.UserCreds()
244
 
    user_creds_ref.update(values)
245
 
    user_creds_ref.password = crypt.encrypt(values['password'])
246
 
    user_creds_ref.aws_creds = crypt.encrypt(values['aws_creds'])
 
262
    if values.get('trust_id'):
 
263
        user_creds_ref.trust_id = crypt.encrypt(values.get('trust_id'))
 
264
        user_creds_ref.trustor_user_id = values.get('trustor_user_id')
 
265
        user_creds_ref.username = None
 
266
        user_creds_ref.password = None
 
267
    else:
 
268
        user_creds_ref.update(values)
 
269
        user_creds_ref.password = crypt.encrypt(values['password'])
247
270
    user_creds_ref.save(_session(context))
248
271
    return user_creds_ref
249
272
 
254
277
    # or it can be committed back to the DB in decrypted form
255
278
    result = dict(db_result)
256
279
    result['password'] = crypt.decrypt(result['password'])
257
 
    result['aws_creds'] = crypt.decrypt(result['aws_creds'])
 
280
    result['trust_id'] = crypt.decrypt(result['trust_id'])
258
281
    return result
259
282
 
260
283
 
265
288
 
266
289
 
267
290
def event_get_all(context):
268
 
    results = model_query(context, models.Event).all()
 
291
    stacks = soft_delete_aware_query(context, models.Stack)
 
292
    stack_ids = [stack.id for stack in stacks]
 
293
    results = model_query(context, models.Event).\
 
294
        filter(models.Event.stack_id.in_(stack_ids)).all()
269
295
 
270
296
    return results
271
297
 
272
298
 
273
299
def event_get_all_by_tenant(context):
274
 
    stacks = model_query(context, models.Stack).\
 
300
    stacks = soft_delete_aware_query(context, models.Stack).\
275
301
        filter_by(tenant=context.tenant_id).all()
276
302
    results = []
277
303
    for stack in stacks:
296
322
 
297
323
 
298
324
def watch_rule_get(context, watch_rule_id):
299
 
    result = model_query(context, models.WatchRule).\
300
 
        filter_by(id=watch_rule_id).first()
 
325
    result = model_query(context, models.WatchRule).get(watch_rule_id)
301
326
    return result
302
327
 
303
328
 
375
400
    for d in ds:
376
401
        session.delete(d)
377
402
    session.flush()
 
403
 
 
404
 
 
405
def purge_deleted(age):
 
406
    if age is not None:
 
407
        try:
 
408
            age = int(age)
 
409
        except ValueError:
 
410
            raise exception.Error(_("age should be an integer"))
 
411
        if age < 0:
 
412
            raise exception.Error(_("age should be a positive integer"))
 
413
    else:
 
414
        age = 90
 
415
 
 
416
    time_line = datetime.now() - timedelta(days=age)
 
417
    engine = get_engine()
 
418
    meta = sqlalchemy.MetaData()
 
419
    meta.bind = engine
 
420
 
 
421
    stack = sqlalchemy.Table('stack', meta, autoload=True)
 
422
    event = sqlalchemy.Table('event', meta, autoload=True)
 
423
    raw_template = sqlalchemy.Table('raw_template', meta, autoload=True)
 
424
    user_creds = sqlalchemy.Table('user_creds', meta, autoload=True)
 
425
 
 
426
    stmt = sqlalchemy.select([stack.c.id,
 
427
                              stack.c.raw_template_id,
 
428
                              stack.c.user_creds_id]).\
 
429
        where(stack.c.deleted_at < time_line)
 
430
    deleted_stacks = engine.execute(stmt)
 
431
 
 
432
    for s in deleted_stacks:
 
433
        event_del = event.delete().where(event.c.stack_id == s[0])
 
434
        engine.execute(event_del)
 
435
        stack_del = stack.delete().where(stack.c.id == s[0])
 
436
        engine.execute(stack_del)
 
437
        raw_template_del = raw_template.delete().\
 
438
            where(raw_template.c.id == s[1])
 
439
        engine.execute(raw_template_del)
 
440
        user_creds_del = user_creds.delete().where(user_creds.c.id == s[2])
 
441
        engine.execute(user_creds_del)