0a779b4389
Creating a wrapper driver for l2gw for hte TVD plugin This driver choose the actual driver based on the project id. Change-Id: I2edda8c780b7e14b36e3033108186ad63dd0449e
227 lines
9.3 KiB
Python
227 lines
9.3 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 = "bridge-" + 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
|