diff --git a/doc/source/admin_util.rst b/doc/source/admin_util.rst index 9ef2cffb66..91126af4a4 100644 --- a/doc/source/admin_util.rst +++ b/doc/source/admin_util.rst @@ -391,6 +391,10 @@ DHCP Bindings nsxadmin -r dhcp-binding -o nsx-update --property dhcp_profile_uuid= +- Recreate dhcp server for a neutron network:: + + nsxadmin -r dhcp-binding -o nsx-recreate --property net-id= + Orphaned DHCP Servers ~~~~~~~~~~~~~~~~~~~~~ diff --git a/vmware_nsx/shell/admin/plugins/nsxv3/resources/dhcp_binding.py b/vmware_nsx/shell/admin/plugins/nsxv3/resources/dhcp_binding.py index c2f08e117e..b30527df66 100644 --- a/vmware_nsx/shell/admin/plugins/nsxv3/resources/dhcp_binding.py +++ b/vmware_nsx/shell/admin/plugins/nsxv3/resources/dhcp_binding.py @@ -16,6 +16,8 @@ import netaddr from neutron_lib.callbacks import registry from neutron_lib import constants as const +from neutron_lib import context as neutron_context +from neutron_lib import exceptions from oslo_config import cfg from oslo_log import log as logging @@ -143,9 +145,61 @@ def nsx_update_dhcp_bindings(resource, event, trigger, **kwargs): {'mac': mac, 'ip': ip, 'port': port_id}) +@admin_utils.output_header +def nsx_recreate_dhcp_server(resource, event, trigger, **kwargs): + """Recreate DHCP server & binding for a neutron network""" + if not cfg.CONF.nsx_v3.native_dhcp_metadata: + LOG.error("Native DHCP is disabled.") + return + + errmsg = ("Need to specify net-id property. Add --property net-id=") + if not kwargs.get('property'): + LOG.error("%s", errmsg) + return + properties = admin_utils.parse_multi_keyval_opt(kwargs['property']) + net_id = properties.get('net-id') + if not net_id: + LOG.error("%s", errmsg) + return + + context = neutron_context.get_admin_context() + with utils.NsxV3PluginWrapper() as plugin: + # verify that this is an existing network with dhcp enabled + try: + network = plugin._get_network(context, net_id) + except exceptions.NetworkNotFound: + LOG.error("Network %s was not found", net_id) + return + if plugin._has_no_dhcp_enabled_subnet(context, network): + LOG.error("Network %s has no DHCP enabled subnet", net_id) + return + dhcp_relay = plugin.get_network_az_by_net_id( + context, net_id).dhcp_relay_service + if dhcp_relay: + LOG.error("Native DHCP should not be enabled with dhcp relay") + return + + # find the dhcp subnet of this network + subnet_id = None + for subnet in network.subnets: + if subnet.enable_dhcp: + subnet_id = subnet.id + break + if not subnet_id: + LOG.error("Network %s has no DHCP enabled subnet", net_id) + return + dhcp_subnet = plugin.get_subnet(context, subnet_id) + # disable and re-enable the dhcp + plugin._enable_native_dhcp(context, network, dhcp_subnet) + LOG.info("Done.") + + registry.subscribe(list_dhcp_bindings, constants.DHCP_BINDING, shell.Operations.LIST.value) registry.subscribe(nsx_update_dhcp_bindings, constants.DHCP_BINDING, shell.Operations.NSX_UPDATE.value) +registry.subscribe(nsx_recreate_dhcp_server, + constants.DHCP_BINDING, + shell.Operations.NSX_RECREATE.value) diff --git a/vmware_nsx/shell/admin/plugins/nsxv3/resources/utils.py b/vmware_nsx/shell/admin/plugins/nsxv3/resources/utils.py index 36e425d61e..564b5dc306 100644 --- a/vmware_nsx/shell/admin/plugins/nsxv3/resources/utils.py +++ b/vmware_nsx/shell/admin/plugins/nsxv3/resources/utils.py @@ -174,9 +174,6 @@ class NsxV3PluginWrapper(plugin.NsxV3Plugin): def _init_port_security_profile(self): return True - def _init_dhcp_switching_profile(self): - pass - def _extend_get_network_dict_provider(self, context, net): self._extend_network_dict_provider(context, net) # skip getting the Qos policy ID because get_object calls diff --git a/vmware_nsx/shell/resources.py b/vmware_nsx/shell/resources.py index 36f0b557f7..48e09a70c1 100644 --- a/vmware_nsx/shell/resources.py +++ b/vmware_nsx/shell/resources.py @@ -101,7 +101,8 @@ nsxv3_resources = { Operations.NSX_UPDATE_DHCP_RELAY.value]), constants.DHCP_BINDING: Resource(constants.DHCP_BINDING, [Operations.LIST.value, - Operations.NSX_UPDATE.value]), + Operations.NSX_UPDATE.value, + Operations.NSX_RECREATE.value]), constants.METADATA_PROXY: Resource(constants.METADATA_PROXY, [Operations.LIST.value, Operations.NSX_UPDATE.value,