50afa71853
1.Upgrade pylint to 2.4.4, add exclusions to the tests, and fix some lint errors in the code 2. Fix user creation with GRANT in MySQL 8.0(Ubuntu Focal) In Ubuntu Bionic (18.04) mysql 5.7 version used to create the user implicitly when using using the GRANT. Ubuntu Focal (20.04) has mysql 8.0 and with mysql 8.0 there is no implicit user creation with GRANT. We need to create the user first before using GRANT command. See also commit I97b0dcbb88c6ef7c22e3c55970211bed792bbd0d 3. Remove fwaas from the zuul.yaml 4. Remove DB migration test which is failing ue to FWaaS migration with py38 5. Fix cover tests python version in .tox 6. fix requirememnts Change-Id: I22654a5d5ccaad3185ae3365a90afba1ce870695
507 lines
22 KiB
Python
507 lines
22 KiB
Python
# Copyright 2014 VMware, Inc.
|
|
#
|
|
# All Rights Reserved
|
|
#
|
|
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
|
# not use this file except in compliance with the License. You may obtain
|
|
# a copy of the License at
|
|
#
|
|
# http://www.apache.org/licenses/LICENSE-2.0
|
|
#
|
|
# Unless required by applicable law or agreed to in writing, software
|
|
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
|
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
|
# License for the specific language governing permissions and limitations
|
|
# under the License.
|
|
#
|
|
|
|
from neutron_lib import exceptions as n_exc
|
|
from oslo_config import cfg
|
|
from oslo_db import exception as db_exc
|
|
from oslo_log import log as logging
|
|
from oslo_utils import excutils
|
|
|
|
from vmware_nsx._i18n import _
|
|
from vmware_nsx.api_client import exception as api_exc
|
|
from vmware_nsx.common import exceptions as p_exc
|
|
from vmware_nsx.db import db as nsx_db
|
|
from vmware_nsx.db import lsn_db
|
|
from vmware_nsx.dhcp_meta import constants as const
|
|
from vmware_nsx.nsxlib.mh import lsn as lsn_api
|
|
from vmware_nsx.nsxlib.mh import switch as switch_api
|
|
|
|
LOG = logging.getLogger(__name__)
|
|
|
|
META_CONF = 'metadata-proxy'
|
|
DHCP_CONF = 'dhcp'
|
|
|
|
|
|
lsn_opts = [
|
|
cfg.BoolOpt('sync_on_missing_data', default=False,
|
|
help=_('Pull LSN information from NSX in case it is missing '
|
|
'from the local data store. This is useful to rebuild '
|
|
'the local store in case of server recovery.'))
|
|
]
|
|
|
|
|
|
def register_lsn_opts(config):
|
|
config.CONF.register_opts(lsn_opts, "NSX_LSN")
|
|
|
|
|
|
def get_nsx_switch_ids(session, cluster, neutron_network_id):
|
|
"""Return the NSX switch id for a given neutron network.
|
|
|
|
First lookup for mappings in Neutron database. If no mapping is
|
|
found, query the NSX backend and add the mappings.
|
|
"""
|
|
nsx_switch_ids = nsx_db.get_nsx_switch_ids(
|
|
session, neutron_network_id)
|
|
if not nsx_switch_ids:
|
|
# Find logical switches from backend.
|
|
# This is a rather expensive query, but it won't be executed
|
|
# more than once for each network in Neutron's lifetime
|
|
nsx_switches = switch_api.get_lswitches(cluster, neutron_network_id)
|
|
if not nsx_switches:
|
|
LOG.warning("Unable to find NSX switches for Neutron network "
|
|
"%s", neutron_network_id)
|
|
return []
|
|
nsx_switch_ids = []
|
|
with session.begin(subtransactions=True):
|
|
for nsx_switch in nsx_switches:
|
|
nsx_switch_id = nsx_switch['uuid']
|
|
nsx_switch_ids.append(nsx_switch_id)
|
|
# Create DB mapping
|
|
nsx_db.add_neutron_nsx_network_mapping(
|
|
session,
|
|
neutron_network_id,
|
|
nsx_switch_id)
|
|
return nsx_switch_ids
|
|
|
|
|
|
class LsnManager(object):
|
|
"""Manage LSN entities associated with networks."""
|
|
|
|
def __init__(self, plugin):
|
|
self.plugin = plugin
|
|
|
|
@property
|
|
def cluster(self):
|
|
return self.plugin.cluster
|
|
|
|
def lsn_exists(self, context, network_id):
|
|
"""Return True if a Logical Service Node exists for the network."""
|
|
return self.lsn_get(
|
|
context, network_id, raise_on_err=False) is not None
|
|
|
|
def lsn_get(self, context, network_id, raise_on_err=True):
|
|
"""Retrieve the LSN id associated to the network."""
|
|
try:
|
|
return lsn_api.lsn_for_network_get(self.cluster, network_id)
|
|
except (n_exc.NotFound, api_exc.NsxApiException):
|
|
if raise_on_err:
|
|
LOG.error('Unable to find Logical Service Node for '
|
|
'network %s.',
|
|
network_id)
|
|
raise p_exc.LsnNotFound(entity='network',
|
|
entity_id=network_id)
|
|
LOG.warning('Unable to find Logical Service Node for '
|
|
'the requested network %s.',
|
|
network_id)
|
|
|
|
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 api_exc.NsxApiException:
|
|
err_msg = _('Unable to create LSN for network %s') % network_id
|
|
raise p_exc.NsxPluginException(err_msg=err_msg)
|
|
|
|
def lsn_delete(self, context, lsn_id):
|
|
"""Delete a LSN given its id."""
|
|
try:
|
|
lsn_api.lsn_delete(self.cluster, lsn_id)
|
|
except (n_exc.NotFound, api_exc.NsxApiException):
|
|
LOG.warning('Unable to delete Logical Service Node %s',
|
|
lsn_id)
|
|
|
|
def lsn_delete_by_network(self, context, network_id):
|
|
"""Delete a LSN associated to the network."""
|
|
lsn_id = self.lsn_get(context, network_id, raise_on_err=False)
|
|
if lsn_id:
|
|
self.lsn_delete(context, lsn_id)
|
|
|
|
def lsn_port_get(self, context, network_id, subnet_id, raise_on_err=True):
|
|
"""Retrieve LSN and LSN port for the network and the subnet."""
|
|
lsn_id = self.lsn_get(context, network_id, raise_on_err=raise_on_err)
|
|
if lsn_id:
|
|
try:
|
|
lsn_port_id = lsn_api.lsn_port_by_subnet_get(
|
|
self.cluster, lsn_id, subnet_id)
|
|
except (n_exc.NotFound, api_exc.NsxApiException):
|
|
if raise_on_err:
|
|
LOG.error('Unable to find Logical Service Node Port '
|
|
'for LSN %(lsn_id)s and subnet '
|
|
'%(subnet_id)s',
|
|
{'lsn_id': lsn_id, 'subnet_id': subnet_id})
|
|
raise p_exc.LsnPortNotFound(lsn_id=lsn_id,
|
|
entity='subnet',
|
|
entity_id=subnet_id)
|
|
LOG.warning('Unable to find Logical Service Node Port '
|
|
'for LSN %(lsn_id)s and subnet '
|
|
'%(subnet_id)s',
|
|
{'lsn_id': lsn_id, 'subnet_id': subnet_id})
|
|
return (lsn_id, None)
|
|
else:
|
|
return (lsn_id, lsn_port_id)
|
|
else:
|
|
return (None, None)
|
|
|
|
def lsn_port_get_by_mac(self, context, network_id, mac, raise_on_err=True):
|
|
"""Retrieve LSN and LSN port given network and mac address."""
|
|
lsn_id = self.lsn_get(context, network_id, raise_on_err=raise_on_err)
|
|
if lsn_id:
|
|
try:
|
|
lsn_port_id = lsn_api.lsn_port_by_mac_get(
|
|
self.cluster, lsn_id, mac)
|
|
except (n_exc.NotFound, api_exc.NsxApiException):
|
|
if raise_on_err:
|
|
LOG.error('Unable to find Logical Service Node Port '
|
|
'for LSN %(lsn_id)s and mac address '
|
|
'%(mac)s',
|
|
{'lsn_id': lsn_id, 'mac': mac})
|
|
raise p_exc.LsnPortNotFound(lsn_id=lsn_id,
|
|
entity='MAC',
|
|
entity_id=mac)
|
|
LOG.warning('Unable to find Logical Service Node '
|
|
'Port for LSN %(lsn_id)s and mac address '
|
|
'%(mac)s',
|
|
{'lsn_id': lsn_id, 'mac': mac})
|
|
return (lsn_id, None)
|
|
else:
|
|
return (lsn_id, lsn_port_id)
|
|
else:
|
|
return (None, None)
|
|
|
|
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 api_exc.NsxApiException:
|
|
err_msg = _('Unable to create port for LSN %s') % lsn_id
|
|
raise p_exc.NsxPluginException(err_msg=err_msg)
|
|
|
|
def lsn_port_delete(self, context, lsn_id, lsn_port_id):
|
|
"""Delete a LSN port from the Logical Service Node."""
|
|
try:
|
|
lsn_api.lsn_port_delete(self.cluster, lsn_id, lsn_port_id)
|
|
except (n_exc.NotFound, api_exc.NsxApiException):
|
|
LOG.warning('Unable to delete LSN Port %s', lsn_port_id)
|
|
|
|
def lsn_port_dispose(self, context, network_id, mac_address):
|
|
"""Delete a LSN port given the network and the mac address."""
|
|
lsn_id, lsn_port_id = self.lsn_port_get_by_mac(
|
|
context, network_id, mac_address, raise_on_err=False)
|
|
if lsn_port_id:
|
|
self.lsn_port_delete(context, lsn_id, lsn_port_id)
|
|
if mac_address == const.METADATA_MAC:
|
|
try:
|
|
lswitch_port_id = switch_api.get_port_by_neutron_tag(
|
|
self.cluster, network_id,
|
|
const.METADATA_PORT_ID)['uuid']
|
|
switch_api.delete_port(
|
|
self.cluster, network_id, lswitch_port_id)
|
|
except (n_exc.PortNotFoundOnNetwork,
|
|
api_exc.NsxApiException):
|
|
LOG.warning("Metadata port not found while attempting "
|
|
"to delete it from network %s",
|
|
network_id)
|
|
else:
|
|
LOG.warning("Unable to find Logical Services Node "
|
|
"Port with MAC %s", mac_address)
|
|
|
|
def lsn_port_dhcp_setup(
|
|
self, context, network_id, port_id, port_data, subnet_config=None):
|
|
"""Connect network to LSN via specified port and port_data."""
|
|
try:
|
|
lsn_id = None
|
|
switch_id = get_nsx_switch_ids(
|
|
context.session, self.cluster, network_id)[0]
|
|
lswitch_port_id = switch_api.get_port_by_neutron_tag(
|
|
self.cluster, switch_id, port_id)['uuid']
|
|
lsn_id = self.lsn_get(context, network_id)
|
|
lsn_port_id = self.lsn_port_create(context, lsn_id, port_data)
|
|
except (n_exc.NotFound, p_exc.NsxPluginException):
|
|
raise p_exc.PortConfigurationError(
|
|
net_id=network_id, lsn_id=lsn_id, port_id=port_id)
|
|
else:
|
|
try:
|
|
lsn_api.lsn_port_plug_network(
|
|
self.cluster, lsn_id, lsn_port_id, lswitch_port_id)
|
|
except p_exc.LsnConfigurationConflict:
|
|
self.lsn_port_delete(context, lsn_id, lsn_port_id)
|
|
raise p_exc.PortConfigurationError(
|
|
net_id=network_id, lsn_id=lsn_id, port_id=port_id)
|
|
if subnet_config:
|
|
self.lsn_port_dhcp_configure(
|
|
context, lsn_id, lsn_port_id, subnet_config)
|
|
else:
|
|
return (lsn_id, lsn_port_id)
|
|
|
|
def lsn_port_metadata_setup(self, context, lsn_id, subnet):
|
|
"""Connect subnet to specified LSN."""
|
|
data = {
|
|
"mac_address": const.METADATA_MAC,
|
|
"ip_address": subnet['cidr'],
|
|
"subnet_id": subnet['id']
|
|
}
|
|
network_id = subnet['network_id']
|
|
tenant_id = subnet['tenant_id']
|
|
lswitch_port_id = None
|
|
try:
|
|
switch_id = get_nsx_switch_ids(
|
|
context.session, self.cluster, network_id)[0]
|
|
lswitch_port_id = switch_api.create_lport(
|
|
self.cluster, switch_id, tenant_id,
|
|
const.METADATA_PORT_ID, const.METADATA_PORT_NAME,
|
|
const.METADATA_DEVICE_ID, True)['uuid']
|
|
lsn_port_id = self.lsn_port_create(context, lsn_id, data)
|
|
except (n_exc.NotFound, p_exc.NsxPluginException,
|
|
api_exc.NsxApiException):
|
|
raise p_exc.PortConfigurationError(
|
|
net_id=network_id, lsn_id=lsn_id, port_id=lswitch_port_id)
|
|
else:
|
|
try:
|
|
lsn_api.lsn_port_plug_network(
|
|
self.cluster, lsn_id, lsn_port_id, lswitch_port_id)
|
|
except p_exc.LsnConfigurationConflict:
|
|
self.lsn_port_delete(self.cluster, lsn_id, lsn_port_id)
|
|
switch_api.delete_port(
|
|
self.cluster, network_id, lswitch_port_id)
|
|
raise p_exc.PortConfigurationError(
|
|
net_id=network_id, lsn_id=lsn_id, port_id=lsn_port_id)
|
|
|
|
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, api_exc.NsxApiException):
|
|
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.NsxPluginException(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, api_exc.NsxApiException):
|
|
err_msg = (_('Unable to configure metadata '
|
|
'for subnet %s') % subnet_id)
|
|
LOG.error(err_msg)
|
|
raise p_exc.NsxPluginException(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 _lsn_port_host_conf(self, context, network_id, subnet_id, data, hdlr):
|
|
lsn_id, lsn_port_id = self.lsn_port_get(
|
|
context, network_id, subnet_id, raise_on_err=False)
|
|
try:
|
|
if lsn_id and lsn_port_id:
|
|
hdlr(self.cluster, lsn_id, lsn_port_id, data)
|
|
except (n_exc.NotFound, api_exc.NsxApiException):
|
|
LOG.error('Error while configuring LSN '
|
|
'port %s', lsn_port_id)
|
|
raise p_exc.PortConfigurationError(
|
|
net_id=network_id, lsn_id=lsn_id, port_id=lsn_port_id)
|
|
|
|
def lsn_port_dhcp_host_add(self, context, network_id, subnet_id, host):
|
|
"""Add dhcp host entry to LSN port configuration."""
|
|
self._lsn_port_host_conf(context, network_id, subnet_id, host,
|
|
lsn_api.lsn_port_dhcp_host_add)
|
|
|
|
def lsn_port_dhcp_host_remove(self, context, network_id, subnet_id, host):
|
|
"""Remove dhcp host entry from LSN port configuration."""
|
|
self._lsn_port_host_conf(context, network_id, subnet_id, host,
|
|
lsn_api.lsn_port_dhcp_host_remove)
|
|
|
|
def lsn_port_meta_host_add(self, context, network_id, subnet_id, host):
|
|
"""Add dhcp host entry to LSN port configuration."""
|
|
self._lsn_port_host_conf(context, network_id, subnet_id, host,
|
|
lsn_api.lsn_port_metadata_host_add)
|
|
|
|
def lsn_port_meta_host_remove(self, context, network_id, subnet_id, host):
|
|
"""Remove dhcp host entry from LSN port configuration."""
|
|
self._lsn_port_host_conf(context, network_id, subnet_id, host,
|
|
lsn_api.lsn_port_metadata_host_remove)
|
|
|
|
def lsn_port_update(
|
|
self, context, network_id, subnet_id, dhcp=None, meta=None):
|
|
"""Update the specified configuration for the LSN port."""
|
|
if not dhcp and not meta:
|
|
return
|
|
try:
|
|
lsn_id, lsn_port_id = self.lsn_port_get(
|
|
context, network_id, subnet_id, raise_on_err=False)
|
|
if dhcp and lsn_id and lsn_port_id:
|
|
lsn_api.lsn_port_host_entries_update(
|
|
self.cluster, lsn_id, lsn_port_id, DHCP_CONF, dhcp)
|
|
if meta and lsn_id and lsn_port_id:
|
|
lsn_api.lsn_port_host_entries_update(
|
|
self.cluster, lsn_id, lsn_port_id, META_CONF, meta)
|
|
except api_exc.NsxApiException:
|
|
raise p_exc.PortConfigurationError(
|
|
net_id=network_id, lsn_id=lsn_id, port_id=lsn_port_id)
|
|
|
|
|
|
class PersistentLsnManager(LsnManager):
|
|
"""Add local persistent state to LSN Manager."""
|
|
|
|
def __init__(self, plugin):
|
|
super(PersistentLsnManager, self).__init__(plugin)
|
|
self.sync_on_missing = cfg.CONF.NSX_LSN.sync_on_missing_data
|
|
|
|
def lsn_get(self, context, network_id, raise_on_err=True):
|
|
try:
|
|
obj = lsn_db.lsn_get_for_network(
|
|
context, network_id, raise_on_err=raise_on_err)
|
|
return obj.lsn_id if obj else None
|
|
except p_exc.LsnNotFound:
|
|
with excutils.save_and_reraise_exception() as ctxt:
|
|
ctxt.reraise = False
|
|
if self.sync_on_missing:
|
|
lsn_id = super(PersistentLsnManager, self).lsn_get(
|
|
context, network_id, raise_on_err=raise_on_err)
|
|
self.lsn_save(context, network_id, lsn_id)
|
|
return lsn_id
|
|
if raise_on_err:
|
|
ctxt.reraise = True
|
|
|
|
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.NsxPluginException(err_msg=err_msg)
|
|
|
|
def lsn_create(self, context, network_id):
|
|
lsn_id = super(PersistentLsnManager,
|
|
self).lsn_create(context, network_id)
|
|
try:
|
|
self.lsn_save(context, network_id, lsn_id)
|
|
except p_exc.NsxPluginException:
|
|
with excutils.save_and_reraise_exception():
|
|
super(PersistentLsnManager, self).lsn_delete(context, lsn_id)
|
|
return lsn_id
|
|
|
|
def lsn_delete(self, context, lsn_id):
|
|
lsn_db.lsn_remove(context, lsn_id)
|
|
super(PersistentLsnManager, self).lsn_delete(context, lsn_id)
|
|
|
|
def lsn_port_get(self, context, network_id, subnet_id, raise_on_err=True):
|
|
try:
|
|
obj = lsn_db.lsn_port_get_for_subnet(
|
|
context, subnet_id, raise_on_err=raise_on_err)
|
|
return (obj.lsn_id, obj.lsn_port_id) if obj else (None, None)
|
|
except p_exc.LsnPortNotFound:
|
|
with excutils.save_and_reraise_exception() as ctxt:
|
|
ctxt.reraise = False
|
|
if self.sync_on_missing:
|
|
lsn_id, lsn_port_id = (
|
|
super(PersistentLsnManager, self).lsn_port_get(
|
|
context, network_id, subnet_id,
|
|
raise_on_err=raise_on_err))
|
|
mac_addr = lsn_api.lsn_port_info_get(
|
|
self.cluster, lsn_id, lsn_port_id)['mac_address']
|
|
self.lsn_port_save(
|
|
context, lsn_port_id, subnet_id, mac_addr, lsn_id)
|
|
return (lsn_id, lsn_port_id)
|
|
if raise_on_err:
|
|
ctxt.reraise = True
|
|
|
|
def lsn_port_get_by_mac(self, context, network_id, mac, raise_on_err=True):
|
|
try:
|
|
obj = lsn_db.lsn_port_get_for_mac(
|
|
context, mac, raise_on_err=raise_on_err)
|
|
return (obj.lsn_id, obj.lsn_port_id) if obj else (None, None)
|
|
except p_exc.LsnPortNotFound:
|
|
with excutils.save_and_reraise_exception() as ctxt:
|
|
ctxt.reraise = False
|
|
if self.sync_on_missing:
|
|
lsn_id, lsn_port_id = (
|
|
super(PersistentLsnManager, self).lsn_port_get_by_mac(
|
|
context, network_id, mac,
|
|
raise_on_err=raise_on_err))
|
|
subnet_id = lsn_api.lsn_port_info_get(
|
|
self.cluster, lsn_id, lsn_port_id).get('subnet_id')
|
|
self.lsn_port_save(
|
|
context, lsn_port_id, subnet_id, mac, lsn_id)
|
|
return (lsn_id, lsn_port_id)
|
|
if raise_on_err:
|
|
ctxt.reraise = True
|
|
|
|
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.NsxPluginException(err_msg=err_msg)
|
|
|
|
def lsn_port_create(self, context, lsn_id, subnet_info):
|
|
lsn_port_id = super(PersistentLsnManager,
|
|
self).lsn_port_create(context, lsn_id, subnet_info)
|
|
try:
|
|
self.lsn_port_save(context, lsn_port_id, subnet_info['subnet_id'],
|
|
subnet_info['mac_address'], lsn_id)
|
|
except p_exc.NsxPluginException:
|
|
with excutils.save_and_reraise_exception():
|
|
super(PersistentLsnManager, self).lsn_port_delete(
|
|
context, lsn_id, lsn_port_id)
|
|
return lsn_port_id
|
|
|
|
def lsn_port_delete(self, context, lsn_id, lsn_port_id):
|
|
lsn_db.lsn_port_remove(context, lsn_port_id)
|
|
super(PersistentLsnManager, self).lsn_port_delete(
|
|
context, lsn_id, lsn_port_id)
|