diff --git a/vmware_nsx/dhcp_meta/rpc.py b/vmware_nsx/dhcp_meta/rpc.py index c2277194e9..005d48297a 100644 --- a/vmware_nsx/dhcp_meta/rpc.py +++ b/vmware_nsx/dhcp_meta/rpc.py @@ -15,7 +15,6 @@ # from eventlet import greenthread -import netaddr from neutron_lib import constants as const from neutron_lib import exceptions as ntn_exc from oslo_config import cfg @@ -105,32 +104,36 @@ def handle_router_metadata_access(plugin, context, router_id, interface=None): "the metadata access network")) return ctx_elevated = context.elevated() - device_filter = {'device_id': [router_id], - 'device_owner': const.ROUTER_INTERFACE_OWNERS} - # Retrieve ports calling database plugin - ports = db_base_plugin_v2.NeutronDbPluginV2.get_ports( - plugin, ctx_elevated, filters=device_filter) + on_demand = getattr(plugin_cfg, 'metadata_on_demand', False) try: - if ports: - on_demand = getattr(plugin_cfg, 'metadata_on_demand', False) - if interface: - if (not on_demand or _find_dhcp_disabled_subnet( - plugin, ctx_elevated, ports)) and ( - not _find_metadata_port(plugin, ctx_elevated, ports)): - _create_metadata_access_network( - plugin, ctx_elevated, router_id) - elif (len(ports) == 1 and _find_metadata_port( - plugin, ctx_elevated, ports)) or (on_demand and - not _find_dhcp_disabled_subnet(plugin, ctx_elevated, ports)): + if interface: + # Add interface case + filters = {'device_id': [router_id], + 'device_owner': const.ROUTER_INTERFACE_OWNERS, + 'fixed_ips': {'ip_address': [METADATA_GATEWAY_IP]}} + # Retrieve metadata ports by calling database plugin + ports = db_base_plugin_v2.NeutronDbPluginV2.get_ports( + plugin, ctx_elevated, filters=filters) + if not ports and (not on_demand or + _find_dhcp_disabled_subnet_by_router( + plugin, ctx_elevated, router_id)): + _create_metadata_access_network( + plugin, ctx_elevated, router_id) + else: + # Remove interface case + filters = {'device_id': [router_id], + 'device_owner': const.ROUTER_INTERFACE_OWNERS} + # Retrieve router interface ports by calling database plugin + ports = db_base_plugin_v2.NeutronDbPluginV2.get_ports( + plugin, ctx_elevated, filters=filters) + if len(ports) == 1 or (on_demand and not + _find_dhcp_disabled_subnet_by_port( + plugin, ctx_elevated, ports)): # Delete the internal metadata network if the router port # is the last port left or no more DHCP-disabled subnet # attached to the router. _destroy_metadata_access_network( plugin, ctx_elevated, router_id, ports) - else: - LOG.debug("No router interface found for router '%s'. " - "No metadata access network should be " - "created or destroyed", router_id) # TODO(salvatore-orlando): A better exception handling in the # NSX plugin would allow us to improve error handling here except (ntn_exc.NeutronException, nsx_exc.NsxPluginException, @@ -144,13 +147,11 @@ def handle_router_metadata_access(plugin, context, router_id, interface=None): def _find_metadata_port(plugin, context, ports): for port in ports: for fixed_ip in port['fixed_ips']: - cidr = netaddr.IPNetwork( - plugin.get_subnet(context, fixed_ip['subnet_id'])['cidr']) - if cidr in netaddr.IPNetwork(METADATA_SUBNET_CIDR): + if fixed_ip['ip_address'] == METADATA_GATEWAY_IP: return port -def _find_dhcp_disabled_subnet(plugin, context, ports): +def _find_dhcp_disabled_subnet_by_port(plugin, context, ports): for port in ports: for fixed_ip in port['fixed_ips']: subnet = plugin.get_subnet(context, fixed_ip['subnet_id']) @@ -158,6 +159,14 @@ def _find_dhcp_disabled_subnet(plugin, context, ports): return subnet +def _find_dhcp_disabled_subnet_by_router(plugin, context, router_id): + filters = {'device_id': [router_id], + 'device_owner': const.ROUTER_INTERFACE_OWNERS} + ports = db_base_plugin_v2.NeutronDbPluginV2.get_ports( + plugin, context, filters=filters) + return _find_dhcp_disabled_subnet_by_port(plugin, context, ports) + + def _create_metadata_access_network(plugin, context, router_id): # Add network # Network name is likely to be truncated on NSX