NSX|P+V3: Improve get_ports performance with designate

When the dns extension driver is used, get_ports is very slow
due to a call for plugin.get_netowrk on each port in order to get
the networks dns_domain and avialability zone.
This code uses a direct DB call to get the network dns_domain.
And only if relevant, also uses a DB call to get the availability zone.

Change-Id: I4b0dc4d5c891e82e71dccb5ee2a6d911e8d03e49
This commit is contained in:
Adit Sarfaty 2019-06-20 13:33:28 +03:00
parent bf3f0b67e4
commit 8e9d7610bc
3 changed files with 61 additions and 17 deletions

View File

@ -13,9 +13,9 @@
# License for the specific language governing permissions and limitations # License for the specific language governing permissions and limitations
# under the License. # under the License.
from neutron_lib.api.definitions import availability_zone as az_def
from neutron_lib.api.definitions import dns from neutron_lib.api.definitions import dns
from neutron_lib.api import validators from neutron_lib.api import validators
from neutron_lib.api.validators import availability_zone as az_validator
from neutron_lib.callbacks import events from neutron_lib.callbacks import events
from neutron_lib.callbacks import registry from neutron_lib.callbacks import registry
from neutron_lib.callbacks import resources from neutron_lib.callbacks import resources
@ -26,6 +26,8 @@ from neutron_lib.plugins import directory
from oslo_config import cfg from oslo_config import cfg
from oslo_log import log as logging from oslo_log import log as logging
from neutron.db.models import dns as dns_model
from neutron.db import models_v2
from neutron.services.externaldns import driver from neutron.services.externaldns import driver
from vmware_nsx.common import driver_api from vmware_nsx.common import driver_api
@ -325,28 +327,56 @@ class DNSExtensionDriverNSXv3(DNSExtensionDriver):
LOG.info("DNSExtensionDriverNSXv3 initialization complete") LOG.info("DNSExtensionDriverNSXv3 initialization complete")
self.config_dns_domain = cfg.CONF.nsx_v3.dns_domain self.config_dns_domain = cfg.CONF.nsx_v3.dns_domain
def _get_network_and_az(self, network_id, context): def _get_db_net_dns(self, session, network_id):
db_entry = session.query(dns_model.NetworkDNSDomain).filter_by(
network_id=network_id).first()
if db_entry:
return db_entry.dns_domain
def _get_db_net_az_hints(self, session, network_id):
# TODO(asarfaty): Consider caching networks azs in get_ports
# and use it here
db_entry = session.query(models_v2.Network).filter_by(
id=network_id).first()
if db_entry:
return db_entry.availability_zone_hints
def _get_network_and_az_dns_domain(self, network_id, context):
if not context: if not context:
context = n_context.get_admin_context() context = n_context.get_admin_context()
network = self._get_network(context, network_id) # Getting only the relevant network attributes directly from the DB
if az_def.AZ_HINTS in network and network[az_def.AZ_HINTS]: net_domain = self._get_db_net_dns(context.session, network_id)
az_name = network[az_def.AZ_HINTS][0]
az = self._availability_zones.get_availability_zone(az_name) # Getting the az of the network is relevant only if any of the azs
return network, az # have dns_domain and if there is no net_domain
az = self._availability_zones.get_default_availability_zone() az_domain = None
return network, az if not net_domain and self._availability_zones.non_default_dns_domain:
az = None
net_hints = self._get_db_net_az_hints(context.session, network_id)
if net_hints:
hints = az_validator.convert_az_string_to_list(net_hints)
if hints:
az_name = hints[0]
az = self._availability_zones.get_availability_zone(
az_name)
if not az:
# Get the default availability zone
az = self._availability_zones.get_default_availability_zone()
az_domain = az.dns_domain
return net_domain, az_domain
def _get_dns_domain(self, network_id, context=None): def _get_dns_domain(self, network_id, context=None):
# first try to get the dns_domain configured on the network net_domain, az_domain = self._get_network_and_az_dns_domain(
net, az = self._get_network_and_az(network_id, context) network_id, context)
if net.get('dns_domain'): # first try to use the dns_domain configured on the network
return _dotted_domain(net['dns_domain']) if net_domain:
# try to get the dns-domain from the specific availability zone return _dotted_domain(net_domain)
# try to use the dns-domain from the specific availability zone
# of this network # of this network
if (az.dns_domain and if (az_domain and
_dotted_domain(az.dns_domain) != _dotted_domain(az_domain) !=
_dotted_domain(DNS_DOMAIN_DEFAULT)): _dotted_domain(DNS_DOMAIN_DEFAULT)):
dns_domain = az.dns_domain dns_domain = az_domain
# Global nsx_v3 dns domain # Global nsx_v3 dns domain
elif (self.config_dns_domain and elif (self.config_dns_domain and
(_dotted_domain(self.config_dns_domain) != (_dotted_domain(self.config_dns_domain) !=

View File

@ -154,3 +154,10 @@ class NsxPAvailabilityZones(common_az.ConfiguredAvailabilityZones):
cfg.CONF.nsx_p.availability_zones, cfg.CONF.nsx_p.availability_zones,
NsxPAvailabilityZone, NsxPAvailabilityZone,
default_availability_zones=default_azs) default_availability_zones=default_azs)
self.non_default_dns_domain = self.dns_domain_configured_non_default()
def dns_domain_configured_non_default(self):
for az in self.availability_zones.values():
if az.dns_domain and az.dns_domain != cfg.CONF.nsx_p.dns_domain:
return True
return False

View File

@ -187,9 +187,16 @@ class NsxV3AvailabilityZones(common_az.ConfiguredAvailabilityZones):
cfg.CONF.nsx_v3.availability_zones, cfg.CONF.nsx_v3.availability_zones,
NsxV3AvailabilityZone, NsxV3AvailabilityZone,
default_availability_zones=default_azs) default_availability_zones=default_azs)
self.non_default_dns_domain = self.dns_domain_configured_non_default()
def dhcp_relay_configured(self): def dhcp_relay_configured(self):
for az in self.availability_zones.values(): for az in self.availability_zones.values():
if az.dhcp_relay_service: if az.dhcp_relay_service:
return True return True
return False return False
def dns_domain_configured_non_default(self):
for az in self.availability_zones.values():
if az.dns_domain and az.dns_domain != cfg.CONF.nsx_v3.dns_domain:
return True
return False