summaryrefslogtreecommitdiffstats
path: root/nova/db
diff options
context:
space:
mode:
authorVishvananda Ishaya <vishvananda@gmail.com>2012-09-14 00:21:03 +0000
committerVishvananda Ishaya <vishvananda@gmail.com>2012-09-14 04:55:26 +0000
commit7937144fce54570b2da543663e6ee5e64b1c3cdb (patch)
treeabd5a7c71ac5f970925f15df5046bf1ab4c0e09a /nova/db
parent9e81075621950afd86a129c7c9e8380019e15597 (diff)
Clean up handling of project_only in network_get
There was some funky logic for getting networks to work around the project only decorator. This changes the code to match what we actually want which is: In Flat and FlatDHCP mode non-admins should be able to access networks that belong to their project or networks that have no project_id assigned. In VlanManager, project_id=None projects should not be accessible as this means the project hasn't been assigned yet. The assignment is done with an elevated context. This patch adds some logic to model_query to allow None in the project_only filter and makes network_get_all_by_uuids and network_get use it. fixes bug 1048869 Change-Id: I5377cea87dec8e9d0d9cec84e07128c5c6e8dca3
Diffstat (limited to 'nova/db')
-rw-r--r--nova/db/api.py10
-rw-r--r--nova/db/sqlalchemy/api.py40
2 files changed, 25 insertions, 25 deletions
diff --git a/nova/db/api.py b/nova/db/api.py
index 785944d14..de393287a 100644
--- a/nova/db/api.py
+++ b/nova/db/api.py
@@ -810,9 +810,9 @@ def network_disassociate(context, network_id):
return IMPL.network_disassociate(context, network_id)
-def network_get(context, network_id):
+def network_get(context, network_id, project_only="allow_none"):
"""Get a network or raise if it does not exist."""
- return IMPL.network_get(context, network_id)
+ return IMPL.network_get(context, network_id, project_only=project_only)
def network_get_all(context):
@@ -820,9 +820,11 @@ def network_get_all(context):
return IMPL.network_get_all(context)
-def network_get_all_by_uuids(context, network_uuids, project_id=None):
+def network_get_all_by_uuids(context, network_uuids,
+ project_only="allow_none"):
"""Return networks by ids."""
- return IMPL.network_get_all_by_uuids(context, network_uuids, project_id)
+ return IMPL.network_get_all_by_uuids(context, network_uuids,
+ project_only=project_only)
# pylint: disable=C0103
diff --git a/nova/db/sqlalchemy/api.py b/nova/db/sqlalchemy/api.py
index f39856cc6..ea8d7cbec 100644
--- a/nova/db/sqlalchemy/api.py
+++ b/nova/db/sqlalchemy/api.py
@@ -188,20 +188,21 @@ def require_aggregate_exists(f):
return wrapper
-def model_query(context, *args, **kwargs):
+def model_query(context, model, *args, **kwargs):
"""Query helper that accounts for context's `read_deleted` field.
:param context: context to query under
:param session: if present, the session to use
:param read_deleted: if present, overrides context's read_deleted field.
:param project_only: if present and context is user-type, then restrict
- query to match the context's project_id.
+ query to match the context's project_id. If set to 'allow_none',
+ restriction includes project_id = None.
"""
session = kwargs.get('session') or get_session()
read_deleted = kwargs.get('read_deleted') or context.read_deleted
- project_only = kwargs.get('project_only')
+ project_only = kwargs.get('project_only', False)
- query = session.query(*args)
+ query = session.query(model, *args)
if read_deleted == 'no':
query = query.filter_by(deleted=False)
@@ -213,8 +214,12 @@ def model_query(context, *args, **kwargs):
raise Exception(
_("Unrecognized read_deleted value '%s'") % read_deleted)
- if project_only and is_user_context(context):
- query = query.filter_by(project_id=context.project_id)
+ if is_user_context(context) and project_only:
+ if project_only == 'allow_none':
+ query = query.filter(or_(model.project_id == context.project_id,
+ model.project_id == None))
+ else:
+ query = query.filter_by(project_id=context.project_id)
return query
@@ -2130,9 +2135,9 @@ def network_disassociate(context, network_id):
@require_context
-def network_get(context, network_id, session=None):
+def network_get(context, network_id, session=None, project_only='allow_none'):
result = model_query(context, models.Network, session=session,
- project_only=True).\
+ project_only=project_only).\
filter_by(id=network_id).\
first()
@@ -2152,24 +2157,17 @@ def network_get_all(context):
return result
-@require_admin_context
-def network_get_all_by_uuids(context, network_uuids, project_id=None):
- project_or_none = or_(models.Network.project_id == project_id,
- models.Network.project_id == None)
- result = model_query(context, models.Network, read_deleted="no").\
+@require_context
+def network_get_all_by_uuids(context, network_uuids,
+ project_only="allow_none"):
+ result = model_query(context, models.Network, read_deleted="no",
+ project_only=project_only).\
filter(models.Network.uuid.in_(network_uuids)).\
- filter(project_or_none).\
all()
if not result:
raise exception.NoNetworksFound()
- #check if host is set to all of the networks
- # returned in the result
- for network in result:
- if network['host'] is None:
- raise exception.NetworkHostNotSet(network_id=network['id'])
-
#check if the result contains all the networks
#we are looking for
for network_uuid in network_uuids:
@@ -2179,7 +2177,7 @@ def network_get_all_by_uuids(context, network_uuids, project_id=None):
found = True
break
if not found:
- if project_id:
+ if project_only:
raise exception.NetworkNotFoundForProject(
network_uuid=network_uuid, project_id=context.project_id)
raise exception.NetworkNotFound(network_id=network_uuid)