Adit Sarfaty e4ef701471 NSX|V: Shorten the L2 bridge edge name
The NSX backend support max length of 40 characters, and the name of the
edge is not used anywhere other than when it is created, so this patch
shorten the name prefix

Change-Id: Iab67c2f7df6dc213beb932e4633e9ff04f7daf66
2018-08-12 07:55:07 +00:00

236 lines
9.5 KiB
Python

# Copyright 2015 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 networking_l2gw.db.l2gateway import l2gateway_db
from networking_l2gw.db.l2gateway import l2gateway_models as models
from networking_l2gw.services.l2gateway.common import constants as l2gw_const
from networking_l2gw.services.l2gateway import exceptions as l2gw_exc
from neutron_lib import exceptions as n_exc
from neutron_lib.plugins import directory
from oslo_log import log as logging
from oslo_utils import uuidutils
from vmware_nsx._i18n import _
from vmware_nsx.common import exceptions as nsx_exc
from vmware_nsx.common import nsxv_constants
from vmware_nsx.db import db as nsx_db
from vmware_nsx.db import nsxv_db
from vmware_nsx.extensions import projectpluginmap
from vmware_nsx.plugins.nsx_v import availability_zones as nsx_az
from vmware_nsx.plugins.nsx_v.vshield.common import exceptions
LOG = logging.getLogger(__name__)
class NsxvL2GatewayDriver(l2gateway_db.L2GatewayMixin):
"""Class to handle API calls for L2 gateway and NSXv backend."""
def __init__(self, plugin):
super(NsxvL2GatewayDriver, self).__init__()
self._plugin = plugin
self.__core_plugin = None
@property
def _core_plugin(self):
if not self.__core_plugin:
self.__core_plugin = directory.get_plugin()
if self.__core_plugin.is_tvd_plugin():
self.__core_plugin = self.__core_plugin.get_plugin_by_type(
projectpluginmap.NsxPlugins.NSX_V)
return self.__core_plugin
@property
def _nsxv(self):
return self._core_plugin.nsx_v
@property
def _edge_manager(self):
return self._core_plugin.edge_manager
def _validate_device_list(self, devices):
# In NSX-v, one L2 gateway is mapped to one DLR.
# So we expect only one device to be configured as part of
# a L2 gateway resource.
if len(devices) != 1:
msg = _("Only a single device is supported for one L2 gateway")
raise n_exc.InvalidInput(error_message=msg)
def _get_l2gateway_interface(self, context, interface_name):
"""Get all l2gateway_interfaces_by interface_name."""
session = context.session
with session.begin():
return session.query(models.L2GatewayInterface).filter_by(
interface_name=interface_name).all()
def _validate_interface_list(self, context, interfaces):
# In NSXv, interface is mapped to a vDS VLAN port group.
# Since HA is not supported, only one interface is expected
if len(interfaces) != 1:
msg = _("Only a single interface is supported for one L2 gateway")
raise n_exc.InvalidInput(error_message=msg)
if not self._nsxv.vcns.validate_network(interfaces[0]['name']):
msg = _("Configured interface not found")
raise n_exc.InvalidInput(error_message=msg)
interface = self._get_l2gateway_interface(context,
interfaces[0]['name'])
if interface:
msg = _("%s is already used.") % interfaces[0]['name']
raise n_exc.InvalidInput(error_message=msg)
def create_l2_gateway_precommit(self, context, l2_gateway):
pass
def create_l2_gateway_postcommit(self, context, l2_gateway):
pass
def create_l2_gateway(self, context, l2_gateway):
"""Create a logical L2 gateway."""
self._admin_check(context, 'CREATE')
gw = l2_gateway[self.gateway_resource]
devices = gw['devices']
self._validate_device_list(devices)
interfaces = devices[0]['interfaces']
self._validate_interface_list(context, interfaces)
# Create a dedicated DLR
try:
edge_id = self._create_l2_gateway_edge(context)
except nsx_exc.NsxL2GWDeviceNotFound:
LOG.exception("Failed to create backend device "
"for L2 gateway")
raise
devices[0]['device_name'] = edge_id
l2_gateway[self.gateway_resource]['devices'] = devices
return
def update_l2_gateway_precommit(self, context, l2_gateway):
pass
def update_l2_gateway_postcommit(self, context, l2_gateway):
pass
def _create_l2_gateway_edge(self, context):
# Create a dedicated DLR
lrouter = {'name': nsxv_constants.L2_GATEWAY_EDGE,
'id': uuidutils.generate_uuid()}
# Create the router on the default availability zone
availability_zone = (nsx_az.NsxVAvailabilityZones().
get_default_availability_zone())
self._edge_manager.create_lrouter(context,
lrouter, lswitch=None, dist=True,
availability_zone=availability_zone)
edge_binding = nsxv_db.get_nsxv_router_binding(context.session,
lrouter['id'])
if not edge_binding:
raise nsx_exc.NsxL2GWDeviceNotFound()
# Enable edge HA on the DLR
if availability_zone.edge_ha:
edge_id = edge_binding['edge_id']
self._edge_manager.nsxv_manager.update_edge_ha(edge_id)
return edge_binding['edge_id']
def _get_device(self, context, l2gw_id):
devices = self._get_l2_gateway_devices(context, l2gw_id)
return devices[0]
def create_l2_gateway_connection_precommit(self, contex, gw_connection):
pass
def create_l2_gateway_connection_postcommit(self, context, gw_connection):
network_id = gw_connection.get('network_id')
virtual_wire = nsx_db.get_nsx_switch_ids(context.session, network_id)
# In NSX-v, there will be only one device configured per L2 gateway.
# The name of the device shall carry the backend DLR.
l2gw_id = gw_connection.get(l2gw_const.L2GATEWAY_ID)
device = self._get_device(context, l2gw_id)
device_name = device.get('device_name')
device_id = device.get('id')
interface = self._get_l2_gw_interfaces(context, device_id)
interface_name = interface[0].get("interface_name")
# bridge name length cannot exceed 40 characters
bridge_name = "brg-" + uuidutils.generate_uuid()
bridge_dict = {"bridges":
{"bridge":
{"name": bridge_name,
"virtualWire": virtual_wire[0],
"dvportGroup": interface_name}}}
try:
self._nsxv.create_bridge(device_name, bridge_dict)
except exceptions.VcnsApiException:
LOG.exception("Failed to update NSX, "
"rolling back changes on neutron.")
raise l2gw_exc.L2GatewayServiceDriverError(
method='create_l2_gateway_connection_postcommit')
return
def create_l2_gateway_connection(self, context, l2_gateway_connection):
"""Create a L2 gateway connection."""
gw_connection = l2_gateway_connection.get(l2gw_const.
CONNECTION_RESOURCE_NAME)
l2gw_id = gw_connection.get(l2gw_const.L2GATEWAY_ID)
gw_db = self._get_l2_gateway(context, l2gw_id)
if gw_db.network_connections:
raise nsx_exc.NsxL2GWInUse(gateway_id=l2gw_id)
return
def delete_l2_gateway_connection_precommit(self, context,
l2_gateway_connection):
pass
def delete_l2_gateway_connection_postcommit(self, context,
l2_gateway_connection):
pass
def delete_l2_gateway_connection(self, context, l2_gateway_connection):
"""Delete a L2 gateway connection."""
self._admin_check(context, 'DELETE')
gw_connection = self.get_l2_gateway_connection(context,
l2_gateway_connection)
if not gw_connection:
raise l2gw_exc.L2GatewayConnectionNotFound(
l2_gateway_connection)
l2gw_id = gw_connection.get(l2gw_const.L2GATEWAY_ID)
device = self._get_device(context, l2gw_id)
device_name = device.get('device_name')
self._nsxv.delete_bridge(device_name)
def delete_l2_gateway(self, context, l2_gateway):
"""Delete a L2 gateway."""
self._admin_check(context, 'DELETE')
device = self._get_device(context, l2_gateway)
edge_id = device.get('device_name')
rtr_binding = nsxv_db.get_nsxv_router_binding_by_edge(
context.session, edge_id)
if rtr_binding:
self._edge_manager.delete_lrouter(context,
rtr_binding['router_id'])
def delete_l2_gateway_precommit(self, context, l2_gateway):
pass
def delete_l2_gateway_postcommit(self, context, l2_gateway):
pass
def add_port_mac(self, context, port_dict):
"""Process a created Neutron port."""
pass
def delete_port_mac(self, context, port):
"""Process a deleted Neutron port."""
pass