NSX|V3+P: subnet_create performance improvements
1. Improve _validate_external_subnet to get the result directly
from DB instead of a get_networks api call
2. Skip configuration validation in _is_overlay_network as the type
of TZ is validated at plugin init anyway
3. Some nit changes in create_subnet
4. Improve is_ddi_supported to get the network if it was
already retrived
5. Improve _get_net_tz to skip backend access when possible
Change-Id: I24aed399a478e2d391ab7b45fe38e53b77116abb
(cherry picked from commit 253273ca5f
)
This commit is contained in:
parent
caacf33807
commit
bf45936f14
|
@ -368,9 +368,7 @@ class NsxPluginBase(db_base_plugin_v2.NeutronDbPluginV2,
|
||||||
net_db[az_def.AZ_HINTS])
|
net_db[az_def.AZ_HINTS])
|
||||||
|
|
||||||
def _validate_external_subnet(self, context, network_id):
|
def _validate_external_subnet(self, context, network_id):
|
||||||
filters = {'id': [network_id], 'router:external': [True]}
|
if self._network_is_external(context, network_id):
|
||||||
nets = self.get_networks(context, filters=filters)
|
|
||||||
if len(nets) > 0:
|
|
||||||
err_msg = _("Can not enable DHCP on external network")
|
err_msg = _("Can not enable DHCP on external network")
|
||||||
raise n_exc.InvalidInput(error_message=err_msg)
|
raise n_exc.InvalidInput(error_message=err_msg)
|
||||||
|
|
||||||
|
|
|
@ -811,14 +811,18 @@ class NsxPluginV3Base(agentschedulers_db.AZDhcpAgentSchedulerDbMixin,
|
||||||
network[qos_consts.QOS_POLICY_ID] = (qos_com_utils.
|
network[qos_consts.QOS_POLICY_ID] = (qos_com_utils.
|
||||||
get_network_policy_id(context, network['id']))
|
get_network_policy_id(context, network['id']))
|
||||||
|
|
||||||
|
def _translate_net_db_2_dict(self, context, net_db):
|
||||||
|
net_dict = self._make_network_dict(net_db, context=context)
|
||||||
|
self._extend_get_network_dict_provider(context, net_dict)
|
||||||
|
return net_dict
|
||||||
|
|
||||||
def get_network(self, context, id, fields=None):
|
def get_network(self, context, id, fields=None):
|
||||||
with db_api.CONTEXT_READER.using(context):
|
with db_api.CONTEXT_READER.using(context):
|
||||||
# Get network from Neutron database
|
# Get network from Neutron database
|
||||||
network = self._get_network(context, id)
|
network = self._get_network(context, id)
|
||||||
# Don't do field selection here otherwise we won't be able to add
|
# Don't do field selection here otherwise we won't be able to add
|
||||||
# provider networks fields
|
# provider networks fields
|
||||||
net = self._make_network_dict(network, context=context)
|
net = self._translate_net_db_2_dict(context, network)
|
||||||
self._extend_get_network_dict_provider(context, net)
|
|
||||||
return db_utils.resource_fields(net, fields)
|
return db_utils.resource_fields(net, fields)
|
||||||
|
|
||||||
def get_networks(self, context, filters=None, fields=None,
|
def get_networks(self, context, filters=None, fields=None,
|
||||||
|
@ -2018,19 +2022,18 @@ class NsxPluginV3Base(agentschedulers_db.AZDhcpAgentSchedulerDbMixin,
|
||||||
self._validate_host_routes_input(subnet)
|
self._validate_host_routes_input(subnet)
|
||||||
self._validate_subnet_ip_version(subnet['subnet'])
|
self._validate_subnet_ip_version(subnet['subnet'])
|
||||||
|
|
||||||
network = self._get_network(
|
net_id = subnet['subnet']['network_id']
|
||||||
context, subnet['subnet']['network_id'])
|
network = self._get_network(context, net_id)
|
||||||
self._validate_single_ipv6_subnet(context, network, subnet['subnet'])
|
self._validate_single_ipv6_subnet(context, network, subnet['subnet'])
|
||||||
|
|
||||||
# TODO(berlin): public external subnet announcement
|
# TODO(berlin): public external subnet announcement
|
||||||
if self._subnet_with_native_dhcp(subnet['subnet']):
|
if self._subnet_with_native_dhcp(subnet['subnet']):
|
||||||
|
|
||||||
self._validate_external_subnet(context,
|
self._validate_external_subnet(context, net_id)
|
||||||
subnet['subnet']['network_id'])
|
|
||||||
self._ensure_native_dhcp()
|
self._ensure_native_dhcp()
|
||||||
lock = 'nsxv3_network_' + subnet['subnet']['network_id']
|
lock = 'nsxv3_network_' + net_id
|
||||||
ddi_support, ddi_type = self._is_ddi_supported_on_net_with_type(
|
ddi_support, ddi_type = self._is_ddi_supported_on_net_with_type(
|
||||||
context, subnet['subnet']['network_id'])
|
context, net_id, network=network)
|
||||||
with locking.LockManager.get_lock(lock):
|
with locking.LockManager.get_lock(lock):
|
||||||
# Check if it is on an overlay network and is the first
|
# Check if it is on an overlay network and is the first
|
||||||
# DHCP-enabled subnet to create.
|
# DHCP-enabled subnet to create.
|
||||||
|
@ -2052,8 +2055,7 @@ class NsxPluginV3Base(agentschedulers_db.AZDhcpAgentSchedulerDbMixin,
|
||||||
context, created_subnet['id'])
|
context, created_subnet['id'])
|
||||||
self._extension_manager.process_create_subnet(context,
|
self._extension_manager.process_create_subnet(context,
|
||||||
subnet['subnet'], created_subnet)
|
subnet['subnet'], created_subnet)
|
||||||
dhcp_relay = self._get_net_dhcp_relay(
|
dhcp_relay = self._get_net_dhcp_relay(context, net_id)
|
||||||
context, subnet['subnet']['network_id'])
|
|
||||||
if not dhcp_relay:
|
if not dhcp_relay:
|
||||||
if self.nsxlib:
|
if self.nsxlib:
|
||||||
try:
|
try:
|
||||||
|
@ -2072,13 +2074,11 @@ class NsxPluginV3Base(agentschedulers_db.AZDhcpAgentSchedulerDbMixin,
|
||||||
msg = None
|
msg = None
|
||||||
else:
|
else:
|
||||||
msg = (_("Can not create more than one DHCP-enabled "
|
msg = (_("Can not create more than one DHCP-enabled "
|
||||||
"subnet in network %s") %
|
"subnet in network %s") % net_id)
|
||||||
subnet['subnet']['network_id'])
|
|
||||||
else:
|
else:
|
||||||
msg = _("Native DHCP is not supported for %(type)s "
|
msg = _("Native DHCP is not supported for %(type)s "
|
||||||
"network %(id)s") % {
|
"network %(id)s") % {'id': net_id,
|
||||||
'id': subnet['subnet']['network_id'],
|
'type': ddi_type}
|
||||||
'type': ddi_type}
|
|
||||||
if msg:
|
if msg:
|
||||||
LOG.error(msg)
|
LOG.error(msg)
|
||||||
raise n_exc.InvalidInput(error_message=msg)
|
raise n_exc.InvalidInput(error_message=msg)
|
||||||
|
@ -2278,7 +2278,8 @@ class NsxPluginV3Base(agentschedulers_db.AZDhcpAgentSchedulerDbMixin,
|
||||||
if enable_dhcp:
|
if enable_dhcp:
|
||||||
(ddi_support,
|
(ddi_support,
|
||||||
ddi_type) = self._is_ddi_supported_on_net_with_type(
|
ddi_type) = self._is_ddi_supported_on_net_with_type(
|
||||||
context, orig_subnet['network_id'])
|
context, orig_subnet['network_id'],
|
||||||
|
network=network)
|
||||||
if ddi_support:
|
if ddi_support:
|
||||||
if self._has_no_dhcp_enabled_subnet(
|
if self._has_no_dhcp_enabled_subnet(
|
||||||
context, network):
|
context, network):
|
||||||
|
@ -2521,13 +2522,20 @@ class NsxPluginV3Base(agentschedulers_db.AZDhcpAgentSchedulerDbMixin,
|
||||||
def _is_vlan_router_interface_supported(self):
|
def _is_vlan_router_interface_supported(self):
|
||||||
"""Should be implemented by each plugin"""
|
"""Should be implemented by each plugin"""
|
||||||
|
|
||||||
def _is_ddi_supported_on_network(self, context, network_id):
|
def _is_ddi_supported_on_network(self, context, network_id, network=None):
|
||||||
result, _ = self._is_ddi_supported_on_net_with_type(
|
result, _ = self._is_ddi_supported_on_net_with_type(
|
||||||
context, network_id)
|
context, network_id, network=network)
|
||||||
return result
|
return result
|
||||||
|
|
||||||
def _is_ddi_supported_on_net_with_type(self, context, network_id):
|
def _is_ddi_supported_on_net_with_type(self, context, network_id,
|
||||||
net = self.get_network(context, network_id)
|
network=None):
|
||||||
|
# Get the network dictionary from the inputs
|
||||||
|
if network:
|
||||||
|
net = (network if isinstance(network, dict)
|
||||||
|
else self._translate_net_db_2_dict(context, network))
|
||||||
|
else:
|
||||||
|
net = self.get_network(context, network_id)
|
||||||
|
|
||||||
# NSX current does not support transparent VLAN ports for
|
# NSX current does not support transparent VLAN ports for
|
||||||
# DHCP and metadata
|
# DHCP and metadata
|
||||||
if cfg.CONF.vlan_transparent:
|
if cfg.CONF.vlan_transparent:
|
||||||
|
@ -2645,7 +2653,7 @@ class NsxPluginV3Base(agentschedulers_db.AZDhcpAgentSchedulerDbMixin,
|
||||||
not self._has_native_dhcp_metadata()):
|
not self._has_native_dhcp_metadata()):
|
||||||
return
|
return
|
||||||
is_ddi_network = self._is_ddi_supported_on_network(
|
is_ddi_network = self._is_ddi_supported_on_network(
|
||||||
context, network['id'])
|
context, network['id'], network=network)
|
||||||
if is_ddi_network:
|
if is_ddi_network:
|
||||||
# Enable native metadata proxy for this network.
|
# Enable native metadata proxy for this network.
|
||||||
tags = self.nsxlib.build_v3_tags_payload(
|
tags = self.nsxlib.build_v3_tags_payload(
|
||||||
|
|
|
@ -2879,7 +2879,7 @@ class NsxPolicyPlugin(nsx_plugin_common.NsxPluginV3Base):
|
||||||
bindings = nsx_db.get_network_bindings(context.session, network_id)
|
bindings = nsx_db.get_network_bindings(context.session, network_id)
|
||||||
# With NSX plugin, "normal" overlay networks will have no binding
|
# With NSX plugin, "normal" overlay networks will have no binding
|
||||||
if not bindings:
|
if not bindings:
|
||||||
# using the default /AZ overlay_tz
|
# using the default/AZ overlay_tz
|
||||||
return True
|
return True
|
||||||
|
|
||||||
binding = bindings[0]
|
binding = bindings[0]
|
||||||
|
@ -2890,11 +2890,13 @@ class NsxPolicyPlugin(nsx_plugin_common.NsxPluginV3Base):
|
||||||
segment = self.nsxpolicy.segment.get(binding.phy_uuid)
|
segment = self.nsxpolicy.segment.get(binding.phy_uuid)
|
||||||
tz = self._get_nsx_net_tz_id(segment)
|
tz = self._get_nsx_net_tz_id(segment)
|
||||||
if tz:
|
if tz:
|
||||||
|
# This call is cached on the nsxlib side
|
||||||
type = self.nsxpolicy.transport_zone.get_transport_type(
|
type = self.nsxpolicy.transport_zone.get_transport_type(
|
||||||
tz)
|
tz)
|
||||||
return type == nsxlib_consts.TRANSPORT_TYPE_OVERLAY
|
return type == nsxlib_consts.TRANSPORT_TYPE_OVERLAY
|
||||||
|
|
||||||
def _is_ens_tz(self, tz_id):
|
def _is_ens_tz(self, tz_id):
|
||||||
|
# This call is cached on the nsxlib side
|
||||||
mode = self.nsxpolicy.transport_zone.get_host_switch_mode(tz_id)
|
mode = self.nsxpolicy.transport_zone.get_host_switch_mode(tz_id)
|
||||||
return mode == nsxlib_consts.HOST_SWITCH_MODE_ENS
|
return mode == nsxlib_consts.HOST_SWITCH_MODE_ENS
|
||||||
|
|
||||||
|
|
|
@ -895,20 +895,7 @@ class NsxV3Plugin(nsx_plugin_common.NsxPluginV3Base,
|
||||||
bindings = nsx_db.get_network_bindings(context.session, network_id)
|
bindings = nsx_db.get_network_bindings(context.session, network_id)
|
||||||
# With NSX plugin, "normal" overlay networks will have no binding
|
# With NSX plugin, "normal" overlay networks will have no binding
|
||||||
if not bindings:
|
if not bindings:
|
||||||
# check the backend transport zone
|
# using the default/AZ overlay_tz
|
||||||
az = self.get_network_az_by_net_id(context, network_id)
|
|
||||||
tz = az._default_overlay_tz_uuid
|
|
||||||
if tz:
|
|
||||||
backend_type = self.nsxlib.transport_zone.get_transport_type(
|
|
||||||
tz)
|
|
||||||
if (backend_type !=
|
|
||||||
self.nsxlib.transport_zone.TRANSPORT_TYPE_OVERLAY):
|
|
||||||
# This is a misconfiguration
|
|
||||||
LOG.warning("Availability zone %(az)s default overlay TZ "
|
|
||||||
"%(tz)s is of type %(type)s",
|
|
||||||
{'az': az.name, 'tz': tz,
|
|
||||||
'type': backend_type})
|
|
||||||
return False
|
|
||||||
return True
|
return True
|
||||||
binding = bindings[0]
|
binding = bindings[0]
|
||||||
if binding.binding_type == utils.NsxV3NetworkTypes.GENEVE:
|
if binding.binding_type == utils.NsxV3NetworkTypes.GENEVE:
|
||||||
|
@ -919,6 +906,7 @@ class NsxV3Plugin(nsx_plugin_common.NsxPluginV3Base,
|
||||||
ls = self.nsxlib.logical_switch.get(binding.phy_uuid)
|
ls = self.nsxlib.logical_switch.get(binding.phy_uuid)
|
||||||
tz = ls.get('transport_zone_id')
|
tz = ls.get('transport_zone_id')
|
||||||
if tz:
|
if tz:
|
||||||
|
# This call is cached on the nsxlib side
|
||||||
backend_type = self.nsxlib.transport_zone.get_transport_type(
|
backend_type = self.nsxlib.transport_zone.get_transport_type(
|
||||||
tz)
|
tz)
|
||||||
return (backend_type ==
|
return (backend_type ==
|
||||||
|
@ -1460,14 +1448,27 @@ class NsxV3Plugin(nsx_plugin_common.NsxPluginV3Base,
|
||||||
return result
|
return result
|
||||||
|
|
||||||
def _get_net_tz(self, context, net_id):
|
def _get_net_tz(self, context, net_id):
|
||||||
mappings = nsx_db.get_nsx_switch_ids(context.session, net_id)
|
bindings = nsx_db.get_network_bindings(context.session, net_id)
|
||||||
if mappings:
|
if bindings:
|
||||||
nsx_net_id = mappings[0]
|
bind_type = bindings[0].binding_type
|
||||||
if nsx_net_id:
|
if bind_type == utils.NsxV3NetworkTypes.NSX_NETWORK:
|
||||||
nsx_net = self.nsxlib.logical_switch.get(nsx_net_id)
|
# If it is NSX network, return the TZ of the backend LS
|
||||||
return nsx_net.get('transport_zone_id')
|
mappings = nsx_db.get_nsx_switch_ids(context.session, net_id)
|
||||||
|
if mappings and mappings[0]:
|
||||||
|
nsx_net = self.nsxlib.logical_switch.get(mappings[0])
|
||||||
|
return nsx_net.get('transport_zone_id')
|
||||||
|
elif bind_type == utils.NetworkTypes.L3_EXT:
|
||||||
|
# External network has tier0 as phy_uuid
|
||||||
|
return
|
||||||
|
else:
|
||||||
|
return bindings[0].phy_uuid
|
||||||
|
else:
|
||||||
|
# Get the default one for the network AZ
|
||||||
|
az = self.get_network_az_by_net_id(context, net_id)
|
||||||
|
return az._default_overlay_tz_uuid
|
||||||
|
|
||||||
def _is_ens_tz(self, tz_id):
|
def _is_ens_tz(self, tz_id):
|
||||||
|
# This call is cached on the nsxlib side
|
||||||
mode = self.nsxlib.transport_zone.get_host_switch_mode(tz_id)
|
mode = self.nsxlib.transport_zone.get_host_switch_mode(tz_id)
|
||||||
return mode == self.nsxlib.transport_zone.HOST_SWITCH_MODE_ENS
|
return mode == self.nsxlib.transport_zone.HOST_SWITCH_MODE_ENS
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue