The problem seems to be here in the security_groups.py:
def _format_security_group_rule(self, context, rule, group_rule_data=None):
"""Return a security group rule in desired API response format.
If group_rule_data is passed in that is used rather than querying
for it.
"""
sg_rule = {} sg_rule['id'] = rule['id'] sg_rule['parent_group_id'] = rule['parent_group_id'] sg_rule['ip_protocol'] = rule['protocol'] sg_rule['from_port'] = rule['from_port'] sg_rule['to_port'] = rule['to_port'] sg_rule['group'] = {} sg_rule['ip_range'] = {}
if group_rule_data: sg_rule['group'] = group_rule_data
elif rule['group_id']:
try: source_group = self.security_group_api.get( context, id=rule['group_id'])
except exception.SecurityGroupNotFound:
# NOTE(arosen): There is a possible race condition that can
# occur here if two api calls occur concurrently: one that
# lists the security groups and another one that deletes a
# security group rule that has a group_id before the
# group_id is fetched. To handle this if
# SecurityGroupNotFound is raised we return None instead
# of the rule and the caller should ignore the rule. LOG.debug("Security Group ID %s does not exist", rule['group_id']) return sg_rule['group'] = {'name': source_group.get('name'), 'tenant_id': source_group.get('project_id')}
else: sg_rule['ip_range'] = {'cidr': rule['cidr']}
return sg_rule
As you can see it will do a:
elif rule['group_id']: source_group = self.security_group_api.get( context, id=rule['group_id'])
For each result with a group_id it will go to neutron to get the group info.
It could at least cache this within a single API call.
Even better would be if we could ask neutron to give the correct info in a single API call
The problem seems to be here in the security_groups.py:
def _format_ security_ group_rule( self, context, rule, group_rule_ data=None) :
"""Return a security group rule in desired API response format.
If group_rule_data is passed in that is used rather than querying
sg_rule[ 'id'] = rule['id']
sg_rule[ 'parent_ group_id' ] = rule['parent_ group_id' ]
sg_rule[ 'ip_protocol' ] = rule['protocol']
sg_rule[ 'from_port' ] = rule['from_port']
sg_rule[ 'to_port' ] = rule['to_port']
sg_rule[ 'group' ] = {}
sg_rule[ 'ip_range' ] = {}
sg_ rule['group' ] = group_rule_data
source_ group = self.security_ group_api. get(
context, id=rule[ 'group_ id']) SecurityGroupNo tFound: tFound is raised we return None instead
LOG.debug( "Security Group ID %s does not exist",
rule[ 'group_ id'])
return
sg_ rule['group' ] = {'name': source_ group.get( 'name') ,
'tenant_ id': source_ group.get( 'project_ id')}
sg_ rule['ip_ range'] = {'cidr': rule['cidr']}
for it.
"""
sg_rule = {}
if group_rule_data:
elif rule['group_id']:
try:
except exception.
# NOTE(arosen): There is a possible race condition that can
# occur here if two api calls occur concurrently: one that
# lists the security groups and another one that deletes a
# security group rule that has a group_id before the
# group_id is fetched. To handle this if
# SecurityGroupNo
# of the rule and the caller should ignore the rule.
else:
return sg_rule
As you can see it will do a:
source_ group = self.security_ group_api. get(
context, id=rule[ 'group_ id'])
elif rule['group_id']:
For each result with a group_id it will go to neutron to get the group info.
It could at least cache this within a single API call.
Even better would be if we could ask neutron to give the correct info in a single API call