From ec68daecc39d964adb9cb976cd56ab297898ff5d Mon Sep 17 00:00:00 2001 From: Amey Bhide <abhide@vmware.com> Date: Wed, 4 Nov 2015 23:59:04 -0800 Subject: [PATCH] Admin Utility: Update DHCP binding for NSXv edge $ nsxadmin -r dhcp-binding -o nsx-update --property edge-id=edge-15 NSX Plugin in use: nsxv Notify callbacks for dhcp-binding, nsx-update Calling callback tools.python_nsxadmin.admin.plugins.common.utils.nsx_update_dhcp_edge_binding ==== [NSX] Update Dhcp Edge Binding ==== Updating NSXv Edge: edge-15 Change-Id: I3524a5cb7a4418006f157842b35c9519235be1d7 --- .../plugins/nsxv/resources/dhcp_binding.py | 30 ++++++++++- vmware_nsx/plugins/nsx_v/plugin.py | 53 ++----------------- .../plugins/nsx_v/vshield/edge_utils.py | 46 +++++++++++++++- 3 files changed, 77 insertions(+), 52 deletions(-) diff --git a/tools/python_nsxadmin/admin/plugins/nsxv/resources/dhcp_binding.py b/tools/python_nsxadmin/admin/plugins/nsxv/resources/dhcp_binding.py index a651ae191b..0b26f0e065 100644 --- a/tools/python_nsxadmin/admin/plugins/nsxv/resources/dhcp_binding.py +++ b/tools/python_nsxadmin/admin/plugins/nsxv/resources/dhcp_binding.py @@ -16,16 +16,19 @@ import logging from tools.python_nsxadmin.admin.plugins.common import constants - import tools.python_nsxadmin.admin.plugins.common.utils as admin_utils import tools.python_nsxadmin.admin.plugins.nsxv.resources.utils as utils import tools.python_nsxadmin.admin.shell as shell from neutron.callbacks import registry +from neutron.db import db_base_plugin_v2 -from vmware_nsx._i18n import _LI +from vmware_nsx._i18n import _LE, _LI from vmware_nsx.db import nsxv_db +from vmware_nsx.plugins.nsx_v.vshield import edge_utils +from vmware_nsx.plugins.nsx_v.vshield import vcns_driver + LOG = logging.getLogger(__name__) nsxv = utils.get_nsxv_client() @@ -82,6 +85,29 @@ def list_missing_dhcp_bindings(resource, event, trigger, **kwargs): LOG.info(neutron_dhcp_static_bindings - nsx_dhcp_static_bindings) +@admin_utils.output_header +def nsx_update_dhcp_edge_binding(resource, event, trigger, **kwargs): + """Resync DHCP bindings on NSXv Edge""" + + if not kwargs['property']: + LOG.error(_LE("Need to specify edge-id parameter")) + return + else: + properties = admin_utils.parse_multi_keyval_opt(kwargs['property']) + LOG.info(_LI("Updating NSXv Edge: %s"), properties.get('edge-id')) + # Need to create a NeutronDbPlugin object; so that we are able to + # do neutron list-ports. + plugin = db_base_plugin_v2.NeutronDbPluginV2() + nsxv_manager = vcns_driver.VcnsDriver( + edge_utils.NsxVCallbacks(plugin)) + edge_manager = edge_utils.EdgeManager(nsxv_manager, plugin) + edge_manager.update_dhcp_service_config( + neutron_db.context, properties.get('edge-id')) + + registry.subscribe(list_missing_dhcp_bindings, constants.DHCP_BINDING, shell.Operations.LIST.value) +registry.subscribe(nsx_update_dhcp_edge_binding, + constants.DHCP_BINDING, + shell.Operations.NSX_UPDATE.value) diff --git a/vmware_nsx/plugins/nsx_v/plugin.py b/vmware_nsx/plugins/nsx_v/plugin.py index 0116122c56..0b5f691636 100644 --- a/vmware_nsx/plugins/nsx_v/plugin.py +++ b/vmware_nsx/plugins/nsx_v/plugin.py @@ -266,11 +266,10 @@ class NsxVPluginV2(addr_pair_db.AllowedAddressPairsMixin, network_id = neutron_port_db['network_id'] device_owner = neutron_port_db['device_owner'] if device_owner.startswith("compute"): - s_bindings = self._create_static_binding(context, - neutron_port_db) - self.edge_manager.create_dhcp_bindings( - context, neutron_port_db['id'], - network_id, s_bindings) + s_bindings = self.edge_manager.create_static_binding( + context, neutron_port_db) + self.edge_manager.create_dhcp_bindings(context, self.nsx_v, + network_id, s_bindings) def _delete_dhcp_static_binding(self, context, neutron_port_db): @@ -1339,50 +1338,6 @@ class NsxVPluginV2(addr_pair_db.AllowedAddressPairsMixin, LOG.debug("Update the DHCP address group to %s", address_groups) return address_groups - def _create_static_binding(self, context, port): - """Create the DHCP Edge static binding configuration - - <staticBinding> - <macAddress></macAddress> - <ipAddress></ipAddress> - <hostname></hostname> <!--disallow duplicate--> - <defaultGateway></defaultGateway> <!--optional.--> - <primaryNameServer></primaryNameServer> <!--optional--> - <secondaryNameServer></secondaryNameServer> <!--optional--> - </staticBinding> - """ - static_bindings = [] - static_config = {} - static_config['macAddress'] = port['mac_address'] - static_config['hostname'] = port['id'] - static_config['leaseTime'] = cfg.CONF.nsxv.dhcp_lease_time - - for fixed_ip in port['fixed_ips']: - # Query the subnet to get gateway and DNS - try: - subnet_id = fixed_ip['subnet_id'] - subnet = self._get_subnet(context, subnet_id) - except n_exc.SubnetNotFound: - LOG.debug("No related subnet for port %s", port['id']) - continue - # Only configure if subnet has DHCP support - if not subnet['enable_dhcp']: - continue - static_config['ipAddress'] = fixed_ip['ip_address'] - # Set gateway for static binding - static_config['defaultGateway'] = subnet['gateway_ip'] - # set primary and secondary dns - name_servers = [dns['address'] - for dns in subnet['dns_nameservers']] - if len(name_servers) == 1: - static_config['primaryNameServer'] = name_servers[0] - elif len(name_servers) >= 2: - static_config['primaryNameServer'] = name_servers[0] - static_config['secondaryNameServer'] = name_servers[1] - - static_bindings.append(static_config) - return static_bindings - def _extract_external_gw(self, context, router, is_extract=True): r = router['router'] gw_info = attr.ATTR_NOT_SPECIFIED diff --git a/vmware_nsx/plugins/nsx_v/vshield/edge_utils.py b/vmware_nsx/plugins/nsx_v/vshield/edge_utils.py index 692c3e9510..dd53f510e2 100644 --- a/vmware_nsx/plugins/nsx_v/vshield/edge_utils.py +++ b/vmware_nsx/plugins/nsx_v/vshield/edge_utils.py @@ -666,6 +666,50 @@ class EdgeManager(object): lock_file_prefix='nsxv-dhcp-config-'): self.update_dhcp_service_config(context, edge_binding['edge_id']) + def create_static_binding(self, context, port): + """Create the DHCP Edge static binding configuration + + <staticBinding> + <macAddress></macAddress> + <ipAddress></ipAddress> + <hostname></hostname> <!--disallow duplicate--> + <defaultGateway></defaultGateway> <!--optional.--> + <primaryNameServer></primaryNameServer> <!--optional--> + <secondaryNameServer></secondaryNameServer> <!--optional--> + </staticBinding> + """ + static_bindings = [] + static_config = {} + static_config['macAddress'] = port['mac_address'] + static_config['hostname'] = port['id'] + static_config['leaseTime'] = cfg.CONF.nsxv.dhcp_lease_time + + for fixed_ip in port['fixed_ips']: + # Query the subnet to get gateway and DNS + try: + subnet_id = fixed_ip['subnet_id'] + subnet = self.nsxv_plugin._get_subnet(context, subnet_id) + except n_exc.SubnetNotFound: + LOG.debug("No related subnet for port %s", port['id']) + continue + # Only configure if subnet has DHCP support + if not subnet['enable_dhcp']: + continue + static_config['ipAddress'] = fixed_ip['ip_address'] + # Set gateway for static binding + static_config['defaultGateway'] = subnet['gateway_ip'] + # set primary and secondary dns + name_servers = [dns['address'] + for dns in subnet['dns_nameservers']] + if len(name_servers) == 1: + static_config['primaryNameServer'] = name_servers[0] + elif len(name_servers) >= 2: + static_config['primaryNameServer'] = name_servers[0] + static_config['secondaryNameServer'] = name_servers[1] + + static_bindings.append(static_config) + return static_bindings + def update_dhcp_service_config(self, context, edge_id): """Reconfigure the DHCP to the edge.""" # Get all networks attached to the edge @@ -681,7 +725,7 @@ class EdgeManager(object): static_bindings = [] for port in inst_ports: static_bindings.extend( - self.nsxv_plugin._create_static_binding( + self.create_static_binding( context.elevated(), port)) dhcp_request = { 'featureType': "dhcp_4.0",