def update_lrouter_port_ips(cluster, lrouter_id, lport_id, ips_to_add, ips_to_remove): uri = _build_uri_path(LROUTERPORT_RESOURCE, lport_id, lrouter_id) try: port = do_request(HTTP_GET, uri, cluster=cluster) # TODO(salvatore-orlando): Enforce ips_to_add intersection with # ips_to_remove is empty ip_address_set = set(port['ip_addresses']) ip_address_set = ip_address_set - set(ips_to_remove) ip_address_set = ip_address_set | set(ips_to_add) # Set is not JSON serializable - convert to list port['ip_addresses'] = list(ip_address_set) do_request(HTTP_PUT, uri, jsonutils.dumps(port), cluster=cluster) except exception.NotFound as e: # FIXME(salv-orlando):avoid raising different exception data = {'lport_id': lport_id, 'lrouter_id': lrouter_id} msg = (_("Router Port %(lport_id)s not found on router " "%(lrouter_id)s") % data) LOG.exception(msg) raise nvp_exc.NvpPluginException(err_msg=msg) except NvpApiClient.NvpApiException as e: msg = _("An exception occurred while updating IP addresses on a " "router logical port:%s") % str(e) LOG.exception(msg) raise nvp_exc.NvpPluginException(err_msg=msg)
def lsn_create(self, context, network_id): """Create a LSN associated to the network.""" try: return lsn_api.lsn_for_network_create(self.cluster, network_id) except nsxlib.NvpApiClient.NvpApiException: err_msg = _('Unable to create LSN for network %s') % network_id raise p_exc.NvpPluginException(err_msg=err_msg)
def lsn_port_dhcp_configure(self, context, lsn_id, lsn_port_id, subnet): """Enable/disable dhcp services with the given config options.""" is_enabled = subnet["enable_dhcp"] dhcp_options = { "domain_name": cfg.CONF.NSX_DHCP.domain_name, "default_lease_time": cfg.CONF.NSX_DHCP.default_lease_time, } dns_servers = cfg.CONF.NSX_DHCP.extra_domain_name_servers or [] dns_servers.extend(subnet["dns_nameservers"]) if subnet['gateway_ip']: dhcp_options["routers"] = subnet["gateway_ip"] if dns_servers: dhcp_options["domain_name_servers"] = ",".join(dns_servers) if subnet["host_routes"]: dhcp_options["classless_static_routes"] = (",".join( subnet["host_routes"])) try: lsn_api.lsn_port_dhcp_configure(self.cluster, lsn_id, lsn_port_id, is_enabled, dhcp_options) except (n_exc.NotFound, nsxlib.NvpApiClient.NvpApiException): err_msg = (_('Unable to configure dhcp for Logical Service ' 'Node %(lsn_id)s and port %(lsn_port_id)s') % { 'lsn_id': lsn_id, 'lsn_port_id': lsn_port_id }) LOG.error(err_msg) raise p_exc.NvpPluginException(err_msg=err_msg)
def lsn_metadata_configure(self, context, subnet_id, is_enabled): """Configure metadata service for the specified subnet.""" subnet = self.plugin.get_subnet(context, subnet_id) network_id = subnet['network_id'] meta_conf = cfg.CONF.NSX_METADATA metadata_options = { 'metadata_server_ip': meta_conf.metadata_server_address, 'metadata_server_port': meta_conf.metadata_server_port, 'metadata_proxy_shared_secret': meta_conf.metadata_shared_secret } try: lsn_id = self.lsn_get(context, network_id) lsn_api.lsn_metadata_configure(self.cluster, lsn_id, is_enabled, metadata_options) except (p_exc.LsnNotFound, nsxlib.NvpApiClient.NvpApiException): err_msg = (_('Unable to configure metadata ' 'for subnet %s') % subnet_id) LOG.error(err_msg) raise p_exc.NvpPluginException(err_msg=err_msg) if is_enabled: try: # test that the lsn port exists self.lsn_port_get(context, network_id, subnet_id) except p_exc.LsnPortNotFound: # this might happen if subnet had dhcp off when created # so create one, and wire it self.lsn_port_metadata_setup(context, lsn_id, subnet) else: self.lsn_port_dispose(context, network_id, const.METADATA_MAC)
def __init__(self, plugin, cluster, state_sync_interval, req_delay, min_chunk_size, max_rand_delay=0): random.seed() self._nvp_cache = NvpCache() # Store parameters as instance members # NOTE(salv-orlando): apologies if it looks java-ish self._plugin = plugin self._cluster = cluster self._req_delay = req_delay self._sync_interval = state_sync_interval self._max_rand_delay = max_rand_delay # Validate parameters if self._sync_interval < self._req_delay: err_msg = (_("Minimum request delay:%(req_delay)s must not " "exceed synchronization interval:%(sync_interval)s") % { 'req_delay': self._req_delay, 'sync_interval': self._sync_interval }) LOG.error(err_msg) raise nvp_exc.NvpPluginException(err_msg=err_msg) # Backoff time in case of failures while fetching sync data self._sync_backoff = 1 # Store the looping call in an instance variable to allow unit tests # for controlling its lifecycle self._sync_looping_call = _start_loopingcall(min_chunk_size, state_sync_interval, self._synchronize_state)
def _setup_nvp_dhcp_metadata(self): # In agentless mode the following extensions, and related # operations, are not supported; so do not publish them if "agent" in self.supported_extension_aliases: self.supported_extension_aliases.remove("agent") if "dhcp_agent_scheduler" in self.supported_extension_aliases: self.supported_extension_aliases.remove("dhcp_agent_scheduler") nvp_svc.register_dhcp_opts(cfg) nvp_svc.register_metadata_opts(cfg) self.lsn_manager = nvp_svc.LsnManager(self) self.agent_notifiers[const.AGENT_TYPE_DHCP] = ( nvp_svc.DhcpAgentNotifyAPI(self, self.lsn_manager)) # In agentless mode, ports whose owner is DHCP need to # be special cased; so add it to the list of special # owners list if const.DEVICE_OWNER_DHCP not in self.port_special_owners: self.port_special_owners.append(const.DEVICE_OWNER_DHCP) try: error = None nvp_svc.check_services_requirements(self.cluster) except nvp_exc.NvpInvalidVersion: error = _("Unable to run Neutron with config option '%s', as NSX " "does not support it") % config.AgentModes.AGENTLESS except nvp_exc.ServiceClusterUnavailable: error = _("Unmet dependency for config option " "'%s'") % config.AgentModes.AGENTLESS if error: LOG.exception(error) raise nvp_exc.NvpPluginException(err_msg=error)
def setup_dhcpmeta_access(self): """Initialize support for DHCP and Metadata services.""" self._init_extensions() if cfg.CONF.NSX.agent_mode == config.AgentModes.AGENT: self._setup_rpc_dhcp_metadata() mod = nsx_rpc elif cfg.CONF.NSX.agent_mode == config.AgentModes.AGENTLESS: self._setup_nsx_dhcp_metadata() mod = nsx_svc elif cfg.CONF.NSX.agent_mode == config.AgentModes.COMBINED: notifier = self._setup_nsx_dhcp_metadata() self._setup_rpc_dhcp_metadata(notifier=notifier) mod = combined else: error = _("Invalid agent_mode: %s") % cfg.CONF.NSX.agent_mode LOG.error(error) raise nsx_exc.NvpPluginException(err_msg=error) self.handle_network_dhcp_access_delegate = ( mod.handle_network_dhcp_access ) self.handle_port_dhcp_access_delegate = ( mod.handle_port_dhcp_access ) self.handle_port_metadata_access_delegate = ( mod.handle_port_metadata_access ) self.handle_metadata_access_delegate = ( mod.handle_router_metadata_access )
def lsn_save(self, context, network_id, lsn_id): """Save LSN-Network mapping to the DB.""" try: lsn_db.lsn_add(context, network_id, lsn_id) except db_exc.DBError: err_msg = _('Unable to save LSN for network %s') % network_id LOG.exception(err_msg) raise p_exc.NvpPluginException(err_msg=err_msg)
def lsn_port_save(self, context, lsn_port_id, subnet_id, mac_addr, lsn_id): """Save LSN Port information to the DB.""" try: lsn_db.lsn_port_add_for_lsn(context, lsn_port_id, subnet_id, mac_addr, lsn_id) except db_exc.DBError: err_msg = _('Unable to save LSN port for subnet %s') % subnet_id LOG.exception(err_msg) raise p_exc.NvpPluginException(err_msg=err_msg)
def lsn_port_create(self, context, lsn_id, subnet_info): """Create and return LSN port for associated subnet.""" try: return lsn_api.lsn_port_create(self.cluster, lsn_id, subnet_info) except n_exc.NotFound: raise p_exc.LsnNotFound(entity='', entity_id=lsn_id) except nsxlib.NvpApiClient.NvpApiException: err_msg = _('Unable to create port for LSN %s') % lsn_id raise p_exc.NvpPluginException(err_msg=err_msg)
def _check_services_requirements(self): try: error = None nsx_svc.check_services_requirements(self.cluster) except nsx_exc.NvpInvalidVersion: error = _("Unable to run Neutron with config option '%s', as NSX " "does not support it") % cfg.CONF.NSX.agent_mode except nsx_exc.ServiceClusterUnavailable: error = _("Unmet dependency for config option " "'%s'") % cfg.CONF.NSX.agent_mode if error: LOG.exception(error) raise nsx_exc.NvpPluginException(err_msg=error)
def _test_handle_router_metadata_access(self, is_port_found, raise_exc=False): subnet = {'id': 'foo_subnet_id', 'network_id': 'foo_network_id'} interface = {'subnet_id': subnet['id'], 'port_id': 'foo_port_id'} mock_func = self.plugin.lsn_manager.lsn_metadata_configure if not is_port_found: self.plugin.get_port.side_effect = n_exc.NotFound if raise_exc: with mock.patch.object(nvp.l3_db.L3_NAT_db_mixin, 'remove_router_interface') as d: mock_func.side_effect = p_exc.NvpPluginException(err_msg='') self.assertRaises(p_exc.NvpPluginException, nvp.handle_router_metadata_access, self.plugin, mock.ANY, 'foo_router_id', interface) d.assert_called_once_with(mock.ANY, mock.ANY, 'foo_router_id', interface) else: nvp.handle_router_metadata_access(self.plugin, mock.ANY, 'foo_router_id', interface) mock_func.assert_called_once_with(mock.ANY, subnet['id'], is_port_found)
def get_ports(cluster, networks=None, devices=None, tenants=None): vm_filter_obsolete = "" vm_filter = "" tenant_filter = "" # This is used when calling delete_network. Neutron checks to see if # the network has any ports. if networks: # FIXME (Aaron) If we get more than one network_id this won't work lswitch = networks[0] else: lswitch = "*" if devices: for device_id in devices: vm_filter_obsolete = '&'.join([ "tag_scope=vm_id", "tag=%s" % utils.device_id_to_vm_id(device_id, obfuscate=True), vm_filter_obsolete ]) vm_filter = '&'.join([ "tag_scope=vm_id", "tag=%s" % utils.device_id_to_vm_id(device_id), vm_filter ]) if tenants: for tenant in tenants: tenant_filter = '&'.join( ["tag_scope=os_tid", "tag=%s" % tenant, tenant_filter]) nsx_lports = {} lport_fields_str = ("tags,admin_status_enabled,display_name," "fabric_status_up") try: lport_query_path_obsolete = ( "/ws.v1/lswitch/%s/lport?fields=%s&%s%stag_scope=q_port_id" "&relations=LogicalPortStatus" % (lswitch, lport_fields_str, vm_filter_obsolete, tenant_filter)) lport_query_path = ( "/ws.v1/lswitch/%s/lport?fields=%s&%s%stag_scope=q_port_id" "&relations=LogicalPortStatus" % (lswitch, lport_fields_str, vm_filter, tenant_filter)) try: # NOTE(armando-migliaccio): by querying with obsolete tag first # current deployments won't take the performance hit of a double # call. In release L-** or M-**, we might want to swap the calls # as it's likely that ports with the new tag would outnumber the # ones with the old tag ports = get_all_query_pages(lport_query_path_obsolete, cluster) if not ports: ports = get_all_query_pages(lport_query_path, cluster) except exception.NotFound: LOG.warn(_("Lswitch %s not found in NSX"), lswitch) ports = None if ports: for port in ports: for tag in port["tags"]: if tag["scope"] == "q_port_id": nsx_lports[tag["tag"]] = port except Exception: err_msg = _("Unable to get ports") LOG.exception(err_msg) raise nvp_exc.NvpPluginException(err_msg=err_msg) return nsx_lports