Browse Source

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)
changes/64/680364/1
Adit Sarfaty 1 month ago
parent
commit
bf45936f14

+ 1
- 3
vmware_nsx/plugins/common/plugin.py View File

@@ -368,9 +368,7 @@ class NsxPluginBase(db_base_plugin_v2.NeutronDbPluginV2,
368 368
             net_db[az_def.AZ_HINTS])
369 369
 
370 370
     def _validate_external_subnet(self, context, network_id):
371
-        filters = {'id': [network_id], 'router:external': [True]}
372
-        nets = self.get_networks(context, filters=filters)
373
-        if len(nets) > 0:
371
+        if self._network_is_external(context, network_id):
374 372
             err_msg = _("Can not enable DHCP on external network")
375 373
             raise n_exc.InvalidInput(error_message=err_msg)
376 374
 

+ 29
- 21
vmware_nsx/plugins/common_v3/plugin.py View File

@@ -811,14 +811,18 @@ class NsxPluginV3Base(agentschedulers_db.AZDhcpAgentSchedulerDbMixin,
811 811
         network[qos_consts.QOS_POLICY_ID] = (qos_com_utils.
812 812
             get_network_policy_id(context, network['id']))
813 813
 
814
+    def _translate_net_db_2_dict(self, context, net_db):
815
+        net_dict = self._make_network_dict(net_db, context=context)
816
+        self._extend_get_network_dict_provider(context, net_dict)
817
+        return net_dict
818
+
814 819
     def get_network(self, context, id, fields=None):
815 820
         with db_api.CONTEXT_READER.using(context):
816 821
             # Get network from Neutron database
817 822
             network = self._get_network(context, id)
818 823
             # Don't do field selection here otherwise we won't be able to add
819 824
             # provider networks fields
820
-            net = self._make_network_dict(network, context=context)
821
-            self._extend_get_network_dict_provider(context, net)
825
+            net = self._translate_net_db_2_dict(context, network)
822 826
         return db_utils.resource_fields(net, fields)
823 827
 
824 828
     def get_networks(self, context, filters=None, fields=None,
@@ -2018,19 +2022,18 @@ class NsxPluginV3Base(agentschedulers_db.AZDhcpAgentSchedulerDbMixin,
2018 2022
         self._validate_host_routes_input(subnet)
2019 2023
         self._validate_subnet_ip_version(subnet['subnet'])
2020 2024
 
2021
-        network = self._get_network(
2022
-            context, subnet['subnet']['network_id'])
2025
+        net_id = subnet['subnet']['network_id']
2026
+        network = self._get_network(context, net_id)
2023 2027
         self._validate_single_ipv6_subnet(context, network, subnet['subnet'])
2024 2028
 
2025 2029
         # TODO(berlin): public external subnet announcement
2026 2030
         if self._subnet_with_native_dhcp(subnet['subnet']):
2027 2031
 
2028
-            self._validate_external_subnet(context,
2029
-                                           subnet['subnet']['network_id'])
2032
+            self._validate_external_subnet(context, net_id)
2030 2033
             self._ensure_native_dhcp()
2031
-            lock = 'nsxv3_network_' + subnet['subnet']['network_id']
2034
+            lock = 'nsxv3_network_' + net_id
2032 2035
             ddi_support, ddi_type = self._is_ddi_supported_on_net_with_type(
2033
-                context, subnet['subnet']['network_id'])
2036
+                context, net_id, network=network)
2034 2037
             with locking.LockManager.get_lock(lock):
2035 2038
                 # Check if it is on an overlay network and is the first
2036 2039
                 # DHCP-enabled subnet to create.
@@ -2052,8 +2055,7 @@ class NsxPluginV3Base(agentschedulers_db.AZDhcpAgentSchedulerDbMixin,
2052 2055
                                     context, created_subnet['id'])
2053 2056
                         self._extension_manager.process_create_subnet(context,
2054 2057
                             subnet['subnet'], created_subnet)
2055
-                        dhcp_relay = self._get_net_dhcp_relay(
2056
-                            context, subnet['subnet']['network_id'])
2058
+                        dhcp_relay = self._get_net_dhcp_relay(context, net_id)
2057 2059
                         if not dhcp_relay:
2058 2060
                             if self.nsxlib:
2059 2061
                                 try:
@@ -2072,13 +2074,11 @@ class NsxPluginV3Base(agentschedulers_db.AZDhcpAgentSchedulerDbMixin,
2072 2074
                         msg = None
2073 2075
                     else:
2074 2076
                         msg = (_("Can not create more than one DHCP-enabled "
2075
-                                "subnet in network %s") %
2076
-                               subnet['subnet']['network_id'])
2077
+                                "subnet in network %s") % net_id)
2077 2078
                 else:
2078 2079
                     msg = _("Native DHCP is not supported for %(type)s "
2079
-                            "network %(id)s") % {
2080
-                          'id': subnet['subnet']['network_id'],
2081
-                          'type': ddi_type}
2080
+                            "network %(id)s") % {'id': net_id,
2081
+                                                 'type': ddi_type}
2082 2082
                 if msg:
2083 2083
                     LOG.error(msg)
2084 2084
                     raise n_exc.InvalidInput(error_message=msg)
@@ -2278,7 +2278,8 @@ class NsxPluginV3Base(agentschedulers_db.AZDhcpAgentSchedulerDbMixin,
2278 2278
                     if enable_dhcp:
2279 2279
                         (ddi_support,
2280 2280
                          ddi_type) = self._is_ddi_supported_on_net_with_type(
2281
-                            context, orig_subnet['network_id'])
2281
+                            context, orig_subnet['network_id'],
2282
+                            network=network)
2282 2283
                         if ddi_support:
2283 2284
                             if self._has_no_dhcp_enabled_subnet(
2284 2285
                                 context, network):
@@ -2521,13 +2522,20 @@ class NsxPluginV3Base(agentschedulers_db.AZDhcpAgentSchedulerDbMixin,
2521 2522
     def _is_vlan_router_interface_supported(self):
2522 2523
         """Should be implemented by each plugin"""
2523 2524
 
2524
-    def _is_ddi_supported_on_network(self, context, network_id):
2525
+    def _is_ddi_supported_on_network(self, context, network_id, network=None):
2525 2526
         result, _ = self._is_ddi_supported_on_net_with_type(
2526
-            context, network_id)
2527
+            context, network_id, network=network)
2527 2528
         return result
2528 2529
 
2529
-    def _is_ddi_supported_on_net_with_type(self, context, network_id):
2530
-        net = self.get_network(context, network_id)
2530
+    def _is_ddi_supported_on_net_with_type(self, context, network_id,
2531
+                                           network=None):
2532
+        # Get the network dictionary from the inputs
2533
+        if network:
2534
+            net = (network if isinstance(network, dict)
2535
+                   else self._translate_net_db_2_dict(context, network))
2536
+        else:
2537
+            net = self.get_network(context, network_id)
2538
+
2531 2539
         # NSX current does not support transparent VLAN ports for
2532 2540
         # DHCP and metadata
2533 2541
         if cfg.CONF.vlan_transparent:
@@ -2645,7 +2653,7 @@ class NsxPluginV3Base(agentschedulers_db.AZDhcpAgentSchedulerDbMixin,
2645 2653
             not self._has_native_dhcp_metadata()):
2646 2654
             return
2647 2655
         is_ddi_network = self._is_ddi_supported_on_network(
2648
-            context, network['id'])
2656
+            context, network['id'], network=network)
2649 2657
         if is_ddi_network:
2650 2658
             # Enable native metadata proxy for this network.
2651 2659
             tags = self.nsxlib.build_v3_tags_payload(

+ 3
- 1
vmware_nsx/plugins/nsx_p/plugin.py View File

@@ -2879,7 +2879,7 @@ class NsxPolicyPlugin(nsx_plugin_common.NsxPluginV3Base):
2879 2879
         bindings = nsx_db.get_network_bindings(context.session, network_id)
2880 2880
         # With NSX plugin, "normal" overlay networks will have no binding
2881 2881
         if not bindings:
2882
-            # using the default /AZ overlay_tz
2882
+            # using the default/AZ overlay_tz
2883 2883
             return True
2884 2884
 
2885 2885
         binding = bindings[0]
@@ -2890,11 +2890,13 @@ class NsxPolicyPlugin(nsx_plugin_common.NsxPluginV3Base):
2890 2890
             segment = self.nsxpolicy.segment.get(binding.phy_uuid)
2891 2891
             tz = self._get_nsx_net_tz_id(segment)
2892 2892
             if tz:
2893
+                # This call is cached on the nsxlib side
2893 2894
                 type = self.nsxpolicy.transport_zone.get_transport_type(
2894 2895
                     tz)
2895 2896
                 return type == nsxlib_consts.TRANSPORT_TYPE_OVERLAY
2896 2897
 
2897 2898
     def _is_ens_tz(self, tz_id):
2899
+        # This call is cached on the nsxlib side
2898 2900
         mode = self.nsxpolicy.transport_zone.get_host_switch_mode(tz_id)
2899 2901
         return mode == nsxlib_consts.HOST_SWITCH_MODE_ENS
2900 2902
 

+ 21
- 20
vmware_nsx/plugins/nsx_v3/plugin.py View File

@@ -895,20 +895,7 @@ class NsxV3Plugin(nsx_plugin_common.NsxPluginV3Base,
895 895
         bindings = nsx_db.get_network_bindings(context.session, network_id)
896 896
         # With NSX plugin, "normal" overlay networks will have no binding
897 897
         if not bindings:
898
-            # check the backend transport zone
899
-            az = self.get_network_az_by_net_id(context, network_id)
900
-            tz = az._default_overlay_tz_uuid
901
-            if tz:
902
-                backend_type = self.nsxlib.transport_zone.get_transport_type(
903
-                    tz)
904
-                if (backend_type !=
905
-                    self.nsxlib.transport_zone.TRANSPORT_TYPE_OVERLAY):
906
-                    # This is a misconfiguration
907
-                    LOG.warning("Availability zone %(az)s default overlay TZ "
908
-                                "%(tz)s is of type %(type)s",
909
-                                {'az': az.name, 'tz': tz,
910
-                                 'type': backend_type})
911
-                    return False
898
+            # using the default/AZ overlay_tz
912 899
             return True
913 900
         binding = bindings[0]
914 901
         if binding.binding_type == utils.NsxV3NetworkTypes.GENEVE:
@@ -919,6 +906,7 @@ class NsxV3Plugin(nsx_plugin_common.NsxPluginV3Base,
919 906
             ls = self.nsxlib.logical_switch.get(binding.phy_uuid)
920 907
             tz = ls.get('transport_zone_id')
921 908
             if tz:
909
+                # This call is cached on the nsxlib side
922 910
                 backend_type = self.nsxlib.transport_zone.get_transport_type(
923 911
                     tz)
924 912
                 return (backend_type ==
@@ -1460,14 +1448,27 @@ class NsxV3Plugin(nsx_plugin_common.NsxPluginV3Base,
1460 1448
         return result
1461 1449
 
1462 1450
     def _get_net_tz(self, context, net_id):
1463
-        mappings = nsx_db.get_nsx_switch_ids(context.session, net_id)
1464
-        if mappings:
1465
-            nsx_net_id = mappings[0]
1466
-            if nsx_net_id:
1467
-                nsx_net = self.nsxlib.logical_switch.get(nsx_net_id)
1468
-                return nsx_net.get('transport_zone_id')
1451
+        bindings = nsx_db.get_network_bindings(context.session, net_id)
1452
+        if bindings:
1453
+            bind_type = bindings[0].binding_type
1454
+            if bind_type == utils.NsxV3NetworkTypes.NSX_NETWORK:
1455
+                # If it is NSX network, return the TZ of the backend LS
1456
+                mappings = nsx_db.get_nsx_switch_ids(context.session, net_id)
1457
+                if mappings and mappings[0]:
1458
+                    nsx_net = self.nsxlib.logical_switch.get(mappings[0])
1459
+                    return nsx_net.get('transport_zone_id')
1460
+            elif bind_type == utils.NetworkTypes.L3_EXT:
1461
+                # External network has tier0 as phy_uuid
1462
+                return
1463
+            else:
1464
+                return bindings[0].phy_uuid
1465
+        else:
1466
+            # Get the default one for the network AZ
1467
+            az = self.get_network_az_by_net_id(context, net_id)
1468
+            return az._default_overlay_tz_uuid
1469 1469
 
1470 1470
     def _is_ens_tz(self, tz_id):
1471
+        # This call is cached on the nsxlib side
1471 1472
         mode = self.nsxlib.transport_zone.get_host_switch_mode(tz_id)
1472 1473
         return mode == self.nsxlib.transport_zone.HOST_SWITCH_MODE_ENS
1473 1474
 

Loading…
Cancel
Save