Merge "Optimize the SG rule retrieval"
This commit is contained in:
commit
9ef180e524
@ -44,6 +44,7 @@ from neutron.extensions import security_groups_default_rules as \
|
||||
from neutron.extensions import securitygroup as ext_sg
|
||||
from neutron.objects import base as base_obj
|
||||
from neutron.objects import ports as port_obj
|
||||
from neutron.objects import rbac_db as rbac_db_obj
|
||||
from neutron.objects import securitygroup as sg_obj
|
||||
from neutron.objects import securitygroup_default_rules as sg_default_rules_obj
|
||||
from neutron import quota
|
||||
@ -131,8 +132,8 @@ class SecurityGroupDbMixin(
|
||||
# be used here otherwise, SG will not be found and error 500 will
|
||||
# be returned through the API
|
||||
get_context = context.elevated() if default_sg else context
|
||||
sg = sg_obj.SecurityGroup.get_object(get_context, id=sg.id)
|
||||
secgroup_dict = self._make_security_group_dict(sg)
|
||||
sg = self._get_security_group(get_context, sg.id)
|
||||
secgroup_dict = self._make_security_group_dict(context, sg)
|
||||
self._registry_publish(resources.SECURITY_GROUP,
|
||||
events.PRECOMMIT_CREATE,
|
||||
exc_cls=ext_sg.SecurityGroupConflict,
|
||||
@ -174,9 +175,10 @@ class SecurityGroupDbMixin(
|
||||
|
||||
sg_objs = sg_obj.SecurityGroup.get_objects(
|
||||
context, _pager=pager, validate_filters=False,
|
||||
fields=fields, **filters)
|
||||
fields=fields, return_db_obj=True, **filters)
|
||||
|
||||
return [self._make_security_group_dict(obj, fields) for obj in sg_objs]
|
||||
return [self._make_security_group_dict(context, obj, fields)
|
||||
for obj in sg_objs]
|
||||
|
||||
@db_api.retry_if_session_inactive()
|
||||
def get_security_groups_count(self, context, filters=None):
|
||||
@ -195,8 +197,8 @@ class SecurityGroupDbMixin(
|
||||
|
||||
try:
|
||||
with db_api.CONTEXT_READER.using(context):
|
||||
ret = self._make_security_group_dict(self._get_security_group(
|
||||
context, id, fields=fields), fields)
|
||||
sg = self._get_security_group(context, id, fields=fields)
|
||||
ret = self._make_security_group_dict(context, sg, fields)
|
||||
if (fields is None or len(fields) == 0 or
|
||||
'security_group_rules' in fields):
|
||||
rules = self.get_security_group_rules(
|
||||
@ -209,12 +211,21 @@ class SecurityGroupDbMixin(
|
||||
context.tenant_id = tmp_context_tenant_id
|
||||
return ret
|
||||
|
||||
def _get_security_group(self, context, id, fields=None):
|
||||
sg = sg_obj.SecurityGroup.get_object(context, fields=fields, id=id)
|
||||
@staticmethod
|
||||
def _get_security_group(context, _id, fields=None):
|
||||
sg = sg_obj.SecurityGroup.get_object(context, fields=fields, id=_id)
|
||||
if sg is None:
|
||||
raise ext_sg.SecurityGroupNotFound(id=id)
|
||||
raise ext_sg.SecurityGroupNotFound(id=_id)
|
||||
return sg
|
||||
|
||||
@staticmethod
|
||||
def _get_security_group_db(context, _id, fields=None):
|
||||
sg_db = sg_obj.SecurityGroup.get_object(
|
||||
context, fields=fields, id=_id, return_db_obj=True)
|
||||
if sg_db is None:
|
||||
raise ext_sg.SecurityGroupNotFound(id=_id)
|
||||
return sg_db
|
||||
|
||||
def _check_security_group(self, context, id, tenant_id=None):
|
||||
if tenant_id:
|
||||
tmp_context_tenant_id = context.tenant_id
|
||||
@ -258,7 +269,7 @@ class SecurityGroupDbMixin(
|
||||
# consistency with deleted rules
|
||||
sg = self._get_security_group(context, id)
|
||||
sgr_ids = [r['id'] for r in sg.rules]
|
||||
sec_group = self._make_security_group_dict(sg)
|
||||
sec_group = self._make_security_group_dict(context, sg)
|
||||
self._registry_publish(resources.SECURITY_GROUP,
|
||||
events.PRECOMMIT_DELETE,
|
||||
exc_cls=ext_sg.SecurityGroupInUse,
|
||||
@ -282,8 +293,8 @@ class SecurityGroupDbMixin(
|
||||
|
||||
if 'stateful' in s:
|
||||
with db_api.CONTEXT_READER.using(context):
|
||||
sg = self._get_security_group(context, id)
|
||||
if s['stateful'] != sg['stateful']:
|
||||
sg_db = self._get_security_group_db(context, id)
|
||||
if s['stateful'] != sg_db['stateful']:
|
||||
filters = {'security_group_id': [id]}
|
||||
ports = self._get_port_security_group_bindings(context,
|
||||
filters)
|
||||
@ -299,11 +310,11 @@ class SecurityGroupDbMixin(
|
||||
sg = self._get_security_group(context, id)
|
||||
if sg.name == 'default' and 'name' in s:
|
||||
raise ext_sg.SecurityGroupCannotUpdateDefault()
|
||||
sg_dict = self._make_security_group_dict(sg)
|
||||
sg_dict = self._make_security_group_dict(context, sg)
|
||||
original_security_group = sg_dict
|
||||
sg.update_fields(s)
|
||||
sg.update()
|
||||
sg_dict = self._make_security_group_dict(sg)
|
||||
sg_dict = self._make_security_group_dict(context, sg)
|
||||
self._registry_publish(
|
||||
resources.SECURITY_GROUP,
|
||||
events.PRECOMMIT_UPDATE,
|
||||
@ -320,24 +331,33 @@ class SecurityGroupDbMixin(
|
||||
|
||||
return sg_dict
|
||||
|
||||
def _make_security_group_dict(self, security_group, fields=None):
|
||||
def _make_security_group_dict(self, context, security_group, fields=None):
|
||||
"""Return the security group in a dictionary
|
||||
|
||||
:param context: Neutron API request context.
|
||||
:param security_group: DB object or OVO of the security group.
|
||||
:param fields: list of fields to filter the returned dictionary.
|
||||
:return: a dictionary with the security group definition.
|
||||
"""
|
||||
rules = security_group.rules or []
|
||||
if isinstance(security_group, sg_obj.SecurityGroup):
|
||||
shared = security_group.shared
|
||||
security_group = security_group.db_obj
|
||||
else:
|
||||
rbac_entries = security_group['rbac_entries']
|
||||
shared = rbac_db_obj.RbacNeutronDbObjectMixin.is_network_shared(
|
||||
context, rbac_entries)
|
||||
res = {'id': security_group['id'],
|
||||
'name': security_group['name'],
|
||||
'stateful': security_group['stateful'],
|
||||
'tenant_id': security_group['tenant_id'],
|
||||
'description': security_group['description'],
|
||||
'standard_attr_id': security_group.db_obj.standard_attr_id,
|
||||
'shared': security_group['shared'],
|
||||
'standard_attr_id': security_group.standard_attr_id,
|
||||
'shared': shared,
|
||||
'security_group_rules': [self._make_security_group_rule_dict(r)
|
||||
for r in rules],
|
||||
}
|
||||
if security_group.rules:
|
||||
res['security_group_rules'] = [
|
||||
self._make_security_group_rule_dict(r)
|
||||
for r in security_group.rules
|
||||
]
|
||||
else:
|
||||
res['security_group_rules'] = []
|
||||
resource_extend.apply_funcs(ext_sg.SECURITYGROUPS, res,
|
||||
security_group.db_obj)
|
||||
resource_extend.apply_funcs(ext_sg.SECURITYGROUPS, res, security_group)
|
||||
return db_utils.resource_fields(res, fields)
|
||||
|
||||
@staticmethod
|
||||
|
@ -608,7 +608,7 @@ class NeutronDbObject(NeutronObject, metaclass=DeclarativeObject):
|
||||
return db_api.CONTEXT_READER.using(context)
|
||||
|
||||
@classmethod
|
||||
def get_object(cls, context, fields=None, **kwargs):
|
||||
def get_object(cls, context, fields=None, return_db_obj=False, **kwargs):
|
||||
"""Fetch a single object
|
||||
|
||||
Return the first result of given context or None if the result doesn't
|
||||
@ -620,6 +620,8 @@ class NeutronDbObject(NeutronObject, metaclass=DeclarativeObject):
|
||||
avoid loading synthetic fields when possible, and
|
||||
does not affect db queries. Default is None, which
|
||||
is the same as []. Example: ['id', 'name']
|
||||
:param return_db_obj: return the DB model object instead of loading
|
||||
the OVO; that could save some time.
|
||||
:param kwargs: multiple keys defined by key=value pairs
|
||||
:return: single object of NeutronDbObject class or None
|
||||
"""
|
||||
@ -633,6 +635,8 @@ class NeutronDbObject(NeutronObject, metaclass=DeclarativeObject):
|
||||
with cls.db_context_reader(context):
|
||||
db_obj = obj_db_api.get_object(
|
||||
cls, context, **cls.modify_fields_to_db(kwargs))
|
||||
if return_db_obj:
|
||||
return db_obj
|
||||
if db_obj:
|
||||
return cls._load_object(context, db_obj, fields=fields)
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user