Merge "Improve performance of security group DB query"
This commit is contained in:
commit
da00b8ddb0
@ -19,6 +19,7 @@ from sqlalchemy.orm import exc
|
|||||||
from neutron.common import constants as q_const
|
from neutron.common import constants as q_const
|
||||||
from neutron.common import ipv6_utils as ipv6
|
from neutron.common import ipv6_utils as ipv6
|
||||||
from neutron.common import utils
|
from neutron.common import utils
|
||||||
|
from neutron.db import allowedaddresspairs_db as addr_pair
|
||||||
from neutron.db import models_v2
|
from neutron.db import models_v2
|
||||||
from neutron.db import securitygroups_db as sg_db
|
from neutron.db import securitygroups_db as sg_db
|
||||||
from neutron.extensions import securitygroup as ext_sg
|
from neutron.extensions import securitygroup as ext_sg
|
||||||
@ -230,27 +231,32 @@ class SecurityGroupServerRpcMixin(sg_db.SecurityGroupDbMixin):
|
|||||||
if not remote_group_ids:
|
if not remote_group_ids:
|
||||||
return ips_by_group
|
return ips_by_group
|
||||||
for remote_group_id in remote_group_ids:
|
for remote_group_id in remote_group_ids:
|
||||||
ips_by_group[remote_group_id] = []
|
ips_by_group[remote_group_id] = set()
|
||||||
|
|
||||||
ip_port = models_v2.IPAllocation.port_id
|
ip_port = models_v2.IPAllocation.port_id
|
||||||
sg_binding_port = sg_db.SecurityGroupPortBinding.port_id
|
sg_binding_port = sg_db.SecurityGroupPortBinding.port_id
|
||||||
sg_binding_sgid = sg_db.SecurityGroupPortBinding.security_group_id
|
sg_binding_sgid = sg_db.SecurityGroupPortBinding.security_group_id
|
||||||
|
|
||||||
|
# Join the security group binding table directly to the IP allocation
|
||||||
|
# table instead of via the Port table skip an unnecessary intermediary
|
||||||
query = context.session.query(sg_binding_sgid,
|
query = context.session.query(sg_binding_sgid,
|
||||||
models_v2.Port,
|
models_v2.IPAllocation.ip_address,
|
||||||
models_v2.IPAllocation.ip_address)
|
addr_pair.AllowedAddressPair.ip_address)
|
||||||
query = query.join(models_v2.IPAllocation,
|
query = query.join(models_v2.IPAllocation,
|
||||||
ip_port == sg_binding_port)
|
ip_port == sg_binding_port)
|
||||||
query = query.join(models_v2.Port,
|
# Outerjoin because address pairs may be null and we still want the
|
||||||
ip_port == models_v2.Port.id)
|
# IP for the port.
|
||||||
|
query = query.outerjoin(
|
||||||
|
addr_pair.AllowedAddressPair,
|
||||||
|
sg_binding_port == addr_pair.AllowedAddressPair.port_id)
|
||||||
query = query.filter(sg_binding_sgid.in_(remote_group_ids))
|
query = query.filter(sg_binding_sgid.in_(remote_group_ids))
|
||||||
for security_group_id, port, ip_address in query:
|
# Each allowed address pair IP record for a port beyond the 1st
|
||||||
ips_by_group[security_group_id].append(ip_address)
|
# will have a duplicate regular IP in the query response since
|
||||||
# if there are allowed_address_pairs add them
|
# the relationship is 1-to-many. Dedup with a set
|
||||||
if getattr(port, 'allowed_address_pairs', None):
|
for security_group_id, ip_address, allowed_addr_ip in query:
|
||||||
for address_pair in port.allowed_address_pairs:
|
ips_by_group[security_group_id].add(ip_address)
|
||||||
ips_by_group[security_group_id].append(
|
if allowed_addr_ip:
|
||||||
address_pair['ip_address'])
|
ips_by_group[security_group_id].add(allowed_addr_ip)
|
||||||
return ips_by_group
|
return ips_by_group
|
||||||
|
|
||||||
def _select_remote_group_ids(self, ports):
|
def _select_remote_group_ids(self, ports):
|
||||||
|
Loading…
Reference in New Issue
Block a user