247
245
# OK, filtering on this key; what value do we search for?
248
246
value = filters.pop(key)
250
if isinstance(value, (list, tuple, set, frozenset)):
248
if key == 'metadata':
249
column_attr = getattr(model, key)
250
if isinstance(value, list):
252
for k, v in item.iteritems():
253
query = query.filter(column_attr.any(key=k))
254
query = query.filter(column_attr.any(value=v))
257
for k, v in value.iteritems():
258
query = query.filter(column_attr.any(key=k))
259
query = query.filter(column_attr.any(value=v))
260
elif isinstance(value, (list, tuple, set, frozenset)):
251
261
# Looking for values in a list; apply to query directly
252
262
column_attr = getattr(model, key)
253
263
query = query.filter(column_attr.in_(value))
632
641
return compute_node
644
def compute_node_statistics(context):
645
"""Compute statistics over all compute nodes."""
646
result = model_query(context,
647
func.count(models.ComputeNode.id),
648
func.sum(models.ComputeNode.vcpus),
649
func.sum(models.ComputeNode.memory_mb),
650
func.sum(models.ComputeNode.local_gb),
651
func.sum(models.ComputeNode.vcpus_used),
652
func.sum(models.ComputeNode.memory_mb_used),
653
func.sum(models.ComputeNode.local_gb_used),
654
func.sum(models.ComputeNode.free_ram_mb),
655
func.sum(models.ComputeNode.free_disk_gb),
656
func.sum(models.ComputeNode.current_workload),
657
func.sum(models.ComputeNode.running_vms),
658
func.sum(models.ComputeNode.disk_available_least),
659
read_deleted="no").first()
661
# Build a dict of the info--making no assumptions about result
662
fields = ('count', 'vcpus', 'memory_mb', 'local_gb', 'vcpus_used',
663
'memory_mb_used', 'local_gb_used', 'free_ram_mb', 'free_disk_gb',
664
'current_workload', 'running_vms', 'disk_available_least')
665
return dict((field, int(result[idx] or 0))
666
for idx, field in enumerate(fields))
635
669
###################
1133
1199
# NOTE(sirp): shouldn't we just use project_only here to restrict the
1135
if is_user_context(context) and result['instance_id'] is not None:
1136
instance = instance_get(context, result['instance_id'], session)
1201
if is_user_context(context) and result['instance_uuid'] is not None:
1202
instance = instance_get_by_uuid(context, result['instance_uuid'],
1137
1204
authorize_project_context(context, instance.project_id)
1142
1209
@require_context
1143
def fixed_ip_get_by_instance(context, instance_id):
1210
def fixed_ip_get_by_instance(context, instance_uuid):
1211
if not utils.is_uuid_like(instance_uuid):
1212
raise exception.InvalidUUID(uuid=instance_uuid)
1144
1214
result = model_query(context, models.FixedIp, read_deleted="no").\
1145
filter_by(instance_id=instance_id).\
1215
filter_by(instance_uuid=instance_uuid).\
1149
raise exception.FixedIpNotFoundForInstance(instance_id=instance_id)
1219
raise exception.FixedIpNotFoundForInstance(instance_uuid=instance_uuid)
1254
1324
@require_context
1255
@require_instance_exists
1256
def virtual_interface_get_by_instance(context, instance_id):
1325
@require_instance_exists_using_uuid
1326
def virtual_interface_get_by_instance(context, instance_uuid):
1257
1327
"""Gets all virtual interfaces for instance.
1259
:param instance_id: = id of the instance to retrieve vifs for
1329
:param instance_uuid: = uuid of the instance to retrieve vifs for
1261
1331
vif_refs = _virtual_interface_query(context).\
1262
filter_by(instance_id=instance_id).\
1332
filter_by(instance_uuid=instance_uuid).\
1264
1334
return vif_refs
1267
1337
@require_context
1268
def virtual_interface_get_by_instance_and_network(context, instance_id,
1338
def virtual_interface_get_by_instance_and_network(context, instance_uuid,
1270
1340
"""Gets virtual interface for instance that's associated with network."""
1271
1341
vif_ref = _virtual_interface_query(context).\
1272
filter_by(instance_id=instance_id).\
1342
filter_by(instance_uuid=instance_uuid).\
1273
1343
filter_by(network_id=network_id).\
1545
1578
# Filters for exact matches that we can do along with the SQL query...
1546
1579
# For other filters that don't match this, we will do regexp matching
1547
1580
exact_match_filter_names = ['project_id', 'user_id', 'image_ref',
1548
'vm_state', 'instance_type_id', 'uuid']
1581
'vm_state', 'instance_type_id', 'uuid',
1550
1584
# Filter the query
1551
1585
query_prefix = exact_filter(query_prefix, models.Instance,
1552
1586
filters, exact_match_filter_names)
1588
query_prefix = regex_filter(query_prefix, models.Instance, filters)
1554
1589
instances = query_prefix.all()
1558
# Now filter on everything else for regexp matching..
1559
# For filters not in the list, we'll attempt to use the filter_name
1560
# as a column name in Instance..
1561
regexp_filter_funcs = {}
1593
def regex_filter(query, model, filters):
1594
"""Applies regular expression filtering to a query.
1596
Returns the updated query.
1598
:param query: query to apply filters to
1599
:param model: model object the query applies to
1600
:param filters: dictionary of filters with regex values
1606
'oracle': 'REGEXP_LIKE',
1609
db_string = FLAGS.sql_connection.split(':')[0].split('+')[0]
1610
db_regexp_op = regexp_op_map.get(db_string, 'LIKE')
1563
1611
for filter_name in filters.iterkeys():
1564
filter_func = regexp_filter_funcs.get(filter_name, None)
1565
filter_re = re.compile(str(filters[filter_name]))
1567
filter_l = lambda instance: filter_func(instance, filter_re)
1568
elif filter_name == 'metadata':
1569
filter_l = lambda instance: _regexp_filter_by_metadata(instance,
1570
filters[filter_name])
1572
filter_l = lambda instance: _regexp_filter_by_column(instance,
1573
filter_name, filter_re)
1574
instances = filter(filter_l, instances)
1613
column_attr = getattr(model, filter_name)
1614
except AttributeError:
1616
if 'property' == type(column_attr).__name__:
1618
query = query.filter(column_attr.op(db_regexp_op)(
1619
str(filters[filter_name])))
1581
1623
@require_context
1582
def instance_get_active_by_window(context, begin, end=None, project_id=None):
1624
def instance_get_active_by_window(context, begin, end=None,
1625
project_id=None, host=None):
1583
1626
"""Return instances that were active during window."""
1584
1627
session = get_session()
1585
1628
query = session.query(models.Instance)
2306
2362
###################
2309
@require_admin_context
2310
def auth_token_destroy(context, token_id):
2311
session = get_session()
2312
with session.begin():
2313
token_ref = auth_token_get(context, token_id, session=session)
2314
token_ref.delete(session=session)
2317
@require_admin_context
2318
def auth_token_get(context, token_hash, session=None):
2319
result = model_query(context, models.AuthToken, session=session).\
2320
filter_by(token_hash=token_hash).\
2324
raise exception.AuthTokenNotFound(token=token_hash)
2329
@require_admin_context
2330
def auth_token_update(context, token_hash, values):
2331
session = get_session()
2332
with session.begin():
2333
token_ref = auth_token_get(context, token_hash, session=session)
2334
token_ref.update(values)
2335
token_ref.save(session=session)
2338
@require_admin_context
2339
def auth_token_create(context, token):
2340
tk = models.AuthToken()
2349
2365
@require_context
2350
2366
def quota_get(context, project_id, resource, session=None):
2351
2367
result = model_query(context, models.Quota, session=session,
2777
2788
def reservation_commit(context, reservations):
2778
2789
session = get_session()
2779
2790
with session.begin():
2791
usages = _get_quota_usages(context, session)
2780
2793
for reservation in _quota_reservations(session, context, reservations):
2794
usage = usages[reservation.resource]
2781
2795
if reservation.delta >= 0:
2782
reservation.usage.reserved -= reservation.delta
2783
reservation.usage.in_use += reservation.delta
2796
usage.reserved -= reservation.delta
2797
usage.in_use += reservation.delta
2785
reservation.usage.save(session=session)
2786
2799
reservation.delete(session=session)
2801
for usage in usages.values():
2802
usage.save(session=session)
2789
2805
@require_context
2790
2806
def reservation_rollback(context, reservations):
2791
2807
session = get_session()
2792
2808
with session.begin():
2809
usages = _get_quota_usages(context, session)
2793
2811
for reservation in _quota_reservations(session, context, reservations):
2812
usage = usages[reservation.resource]
2794
2813
if reservation.delta >= 0:
2795
reservation.usage.reserved -= reservation.delta
2796
reservation.usage.save(session=session)
2814
usage.reserved -= reservation.delta
2798
2816
reservation.delete(session=session)
2818
for usage in usages.values():
2819
usage.save(session=session)
2801
2822
@require_admin_context
2802
2823
def quota_destroy_all_by_project(context, project_id):
3624
3657
###################
3627
@require_admin_context
3628
def user_get(context, id, session=None):
3629
result = model_query(context, models.User, session=session).\
3634
raise exception.UserNotFound(user_id=id)
3639
@require_admin_context
3640
def user_get_by_access_key(context, access_key, session=None):
3641
result = model_query(context, models.User, session=session).\
3642
filter_by(access_key=access_key).\
3646
raise exception.AccessKeyNotFound(access_key=access_key)
3651
@require_admin_context
3652
def user_create(context, values):
3653
user_ref = models.User()
3654
user_ref.update(values)
3659
@require_admin_context
3660
def user_delete(context, id):
3661
session = get_session()
3662
with session.begin():
3663
session.query(models.UserProjectAssociation).\
3664
filter_by(user_id=id).\
3666
session.query(models.UserRoleAssociation).\
3667
filter_by(user_id=id).\
3669
session.query(models.UserProjectRoleAssociation).\
3670
filter_by(user_id=id).\
3672
user_ref = user_get(context, id, session=session)
3673
session.delete(user_ref)
3676
def user_get_all(context):
3677
return model_query(context, models.User).all()
3680
def user_get_roles(context, user_id):
3681
session = get_session()
3682
with session.begin():
3683
user_ref = user_get(context, user_id, session=session)
3684
return [role.role for role in user_ref['roles']]
3687
def user_get_roles_for_project(context, user_id, project_id):
3688
session = get_session()
3689
with session.begin():
3690
res = session.query(models.UserProjectRoleAssociation).\
3691
filter_by(user_id=user_id).\
3692
filter_by(project_id=project_id).\
3694
return [association.role for association in res]
3697
def user_remove_project_role(context, user_id, project_id, role):
3698
session = get_session()
3699
with session.begin():
3700
session.query(models.UserProjectRoleAssociation).\
3701
filter_by(user_id=user_id).\
3702
filter_by(project_id=project_id).\
3703
filter_by(role=role).\
3707
def user_remove_role(context, user_id, role):
3708
session = get_session()
3709
with session.begin():
3710
res = session.query(models.UserRoleAssociation).\
3711
filter_by(user_id=user_id).\
3712
filter_by(role=role).\
3715
session.delete(role)
3718
def user_add_role(context, user_id, role):
3719
session = get_session()
3720
with session.begin():
3721
user_ref = user_get(context, user_id, session=session)
3722
models.UserRoleAssociation(user=user_ref, role=role).\
3723
save(session=session)
3726
def user_add_project_role(context, user_id, project_id, role):
3727
session = get_session()
3728
with session.begin():
3729
user_ref = user_get(context, user_id, session=session)
3730
project_ref = project_get(context, project_id, session=session)
3731
models.UserProjectRoleAssociation(user_id=user_ref['id'],
3732
project_id=project_ref['id'],
3733
role=role).save(session=session)
3736
def user_update(context, user_id, values):
3737
session = get_session()
3738
with session.begin():
3739
user_ref = user_get(context, user_id, session=session)
3740
user_ref.update(values)
3741
user_ref.save(session=session)
3747
def project_create(context, values):
3748
project_ref = models.Project()
3749
project_ref.update(values)
3754
def project_add_member(context, project_id, user_id):
3755
session = get_session()
3756
with session.begin():
3757
project_ref = project_get(context, project_id, session=session)
3758
user_ref = user_get(context, user_id, session=session)
3760
project_ref.members += [user_ref]
3761
project_ref.save(session=session)
3764
def project_get(context, id, session=None):
3765
result = model_query(context, models.Project, session=session,
3766
read_deleted="no").\
3768
options(joinedload_all('members')).\
3772
raise exception.ProjectNotFound(project_id=id)
3777
def project_get_all(context):
3778
return model_query(context, models.Project).\
3779
options(joinedload_all('members')).\
3783
def project_get_by_user(context, user_id):
3784
user = model_query(context, models.User).\
3785
filter_by(id=user_id).\
3786
options(joinedload_all('projects')).\
3790
raise exception.UserNotFound(user_id=user_id)
3792
return user.projects
3795
def project_remove_member(context, project_id, user_id):
3796
session = get_session()
3797
project = project_get(context, project_id, session=session)
3798
user = user_get(context, user_id, session=session)
3800
if user in project.members:
3801
project.members.remove(user)
3802
project.save(session=session)
3805
def project_update(context, project_id, values):
3806
session = get_session()
3807
with session.begin():
3808
project_ref = project_get(context, project_id, session=session)
3809
project_ref.update(values)
3810
project_ref.save(session=session)
3813
def project_delete(context, id):
3814
session = get_session()
3815
with session.begin():
3816
session.query(models.UserProjectAssociation).\
3817
filter_by(project_id=id).\
3819
session.query(models.UserProjectRoleAssociation).\
3820
filter_by(project_id=id).\
3822
project_ref = project_get(context, id, session=session)
3823
session.delete(project_ref)
3826
3660
@require_context
3827
3661
def project_get_networks(context, project_id, associate=True):
3828
3662
# NOTE(tr3buchet): as before this function will associate
4381
4210
@require_context
4382
def bw_usage_update(context,
4211
def bw_usage_update(context, uuid, mac, start_period, bw_in, bw_out,
4212
last_refreshed=None, session=None):
4388
4213
if not session:
4389
4214
session = get_session()
4216
if last_refreshed is None:
4217
last_refreshed = timeutils.utcnow()
4219
# NOTE(comstud): More often than not, we'll be updating records vs
4220
# creating records. Optimize accordingly, trying to update existing
4221
# records. Fall back to creation when no rows are updated.
4391
4222
with session.begin():
4392
bwusage = model_query(context, models.BandwidthUsage,
4223
values = {'last_refreshed': last_refreshed,
4226
rows = model_query(context, models.BandwidthUsage,
4393
4227
session=session, read_deleted="yes").\
4394
4228
filter_by(start_period=start_period).\
4395
4229
filter_by(uuid=uuid).\
4399
bwusage = models.BandwidthUsage()
4400
bwusage.start_period = start_period
4404
bwusage.last_refreshed = timeutils.utcnow()
4230
filter_by(mac=mac).\
4231
update(values, synchronize_session=False)
4235
bwusage = models.BandwidthUsage()
4236
bwusage.start_period = start_period
4239
bwusage.last_refreshed = last_refreshed
4405
4240
bwusage.bw_in = bw_in
4406
4241
bwusage.bw_out = bw_out
4407
4242
bwusage.save(session=session)
4410
4245
####################
4413
def _instance_type_extra_specs_get_query(context, instance_type_id,
4248
def _instance_type_extra_specs_get_query(context, flavor_id,
4250
# Two queries necessary because join with update doesn't work.
4251
t = model_query(context, models.InstanceTypes.id,
4252
session=session, read_deleted="no").\
4253
filter(models.InstanceTypes.flavorid == flavor_id).\
4415
4255
return model_query(context, models.InstanceTypeExtraSpecs,
4416
4256
session=session, read_deleted="no").\
4417
filter_by(instance_type_id=instance_type_id)
4257
filter(models.InstanceTypeExtraSpecs.\
4258
instance_type_id.in_(t))
4420
4261
@require_context
4421
def instance_type_extra_specs_get(context, instance_type_id):
4262
def instance_type_extra_specs_get(context, flavor_id):
4422
4263
rows = _instance_type_extra_specs_get_query(
4423
context, instance_type_id).\
4264
context, flavor_id).\
4433
4274
@require_context
4434
def instance_type_extra_specs_delete(context, instance_type_id, key):
4275
def instance_type_extra_specs_delete(context, flavor_id, key):
4276
# Don't need synchronize the session since we will not use the query result
4435
4277
_instance_type_extra_specs_get_query(
4436
context, instance_type_id).\
4437
filter_by(key=key).\
4278
context, flavor_id).\
4279
filter(models.InstanceTypeExtraSpecs.key == key).\
4438
4280
update({'deleted': True,
4439
4281
'deleted_at': timeutils.utcnow(),
4440
'updated_at': literal_column('updated_at')})
4282
'updated_at': literal_column('updated_at')},
4283
synchronize_session=False)
4443
4286
@require_context
4444
def instance_type_extra_specs_get_item(context, instance_type_id, key,
4287
def instance_type_extra_specs_get_item(context, flavor_id, key,
4446
4289
result = _instance_type_extra_specs_get_query(
4447
context, instance_type_id, session=session).\
4448
filter_by(key=key).\
4290
context, flavor_id, session=session).\
4291
filter(models.InstanceTypeExtraSpecs.key == key).\
4452
4294
raise exception.InstanceTypeExtraSpecsNotFound(
4453
extra_specs_key=key, instance_type_id=instance_type_id)
4295
extra_specs_key=key, instance_type_id=flavor_id)
4458
4300
@require_context
4459
def instance_type_extra_specs_update_or_create(context, instance_type_id,
4301
def instance_type_extra_specs_update_or_create(context, flavor_id,
4461
4303
session = get_session()
4462
4304
spec_ref = None
4305
instance_type = instance_type_get_by_flavor_id(context, flavor_id)
4463
4306
for key, value in specs.iteritems():
4465
4308
spec_ref = instance_type_extra_specs_get_item(
4466
context, instance_type_id, key, session)
4309
context, flavor_id, key, session)
4467
4310
except exception.InstanceTypeExtraSpecsNotFound, e:
4468
4311
spec_ref = models.InstanceTypeExtraSpecs()
4469
4312
spec_ref.update({"key": key, "value": value,
4470
"instance_type_id": instance_type_id,
4313
"instance_type_id": instance_type["id"],
4472
4315
spec_ref.save(session=session)
4950
4789
@require_admin_context
4951
def aggregate_get_by_host(context, host):
4952
aggregate_host = _aggregate_get_query(context,
4953
models.AggregateHost,
4954
models.AggregateHost.host,
4957
if not aggregate_host:
4958
raise exception.AggregateHostNotFound(host=host)
4960
return aggregate_get(context, aggregate_host.aggregate_id)
4790
def aggregate_get_by_host(context, host, key=None):
4791
query = model_query(context, models.Aggregate).join(
4792
"_hosts").filter(models.AggregateHost.host == host)
4795
query = query.join("_metadata").filter(
4796
models.AggregateMetadata.key == key)
4800
@require_admin_context
4801
def aggregate_metadata_get_by_host(context, host, key=None):
4802
query = model_query(context, models.Aggregate).join(
4803
"_hosts").filter(models.AggregateHost.host == host).join(
4807
query = query.filter(models.AggregateMetadata.key == key)
4809
metadata = collections.defaultdict(set)
4811
for kv in agg._metadata:
4812
metadata[kv['key']].add(kv['value'])
4963
4816
@require_admin_context
5210
5059
@require_context
5211
5060
def _ec2_instance_get_query(context, session=None):
5212
5061
return model_query(context, models.InstanceIdMapping, session=session)
5064
@require_admin_context
5065
def task_log_get(context, task_name, period_beginning,
5066
period_ending, host, state=None, session=None):
5067
query = model_query(context, models.TaskLog, session=session).\
5068
filter_by(task_name=task_name).\
5069
filter_by(period_beginning=period_beginning).\
5070
filter_by(period_ending=period_ending).\
5071
filter_by(host=host)
5072
if state is not None:
5073
query = query.filter_by(state=state)
5075
return query.first()
5078
@require_admin_context
5079
def task_log_get_all(context, task_name, period_beginning,
5080
period_ending, host=None, state=None, session=None):
5081
query = model_query(context, models.TaskLog, session=session).\
5082
filter_by(task_name=task_name).\
5083
filter_by(period_beginning=period_beginning).\
5084
filter_by(period_ending=period_ending)
5085
if host is not None:
5086
query = query.filter_by(host=host)
5087
if state is not None:
5088
query = query.filter_by(state=state)
5092
@require_admin_context
5093
def task_log_begin_task(context, task_name,
5100
session = session or get_session()
5101
with session.begin():
5102
task = task_log_get(context, task_name,
5108
#It's already run(ning)!
5109
raise exception.TaskAlreadyRunning(task_name=task_name, host=host)
5110
task = models.TaskLog()
5111
task.task_name = task_name
5112
task.period_beginning = period_beginning
5113
task.period_ending = period_ending
5115
task.state = "RUNNING"
5117
task.message = message
5119
task.task_items = task_items
5120
task.save(session=session)
5124
@require_admin_context
5125
def task_log_end_task(context, task_name,
5132
session = session or get_session()
5133
with session.begin():
5134
task = task_log_get(context, task_name,
5141
raise exception.TaskNotRunning(task_name=task_name, host=host)
5144
task.message = message
5145
task.errors = errors
5146
task.save(session=session)