diff --git a/doc/source/devstack.rst b/doc/source/devstack.rst index 5ada57874a..bbe4811e76 100644 --- a/doc/source/devstack.rst +++ b/doc/source/devstack.rst @@ -331,3 +331,12 @@ Add neutron-vpnaas repo as an external repository and configure following flags [DEFAULT] api_extensions_path = $DEST/neutron-vpnaas/neutron_vpnaas/extensions +IPAM Driver +~~~~~~~~~~~ + +Update the ``local.conf`` file:: + + [[post-config|$NEUTRON_CONF]] + [DEFAULT] + ipam_driver = vmware_nsxtvd_ipam + diff --git a/setup.cfg b/setup.cfg index fef15dae6d..20506e13e5 100644 --- a/setup.cfg +++ b/setup.cfg @@ -54,6 +54,7 @@ neutron.qos.notification_drivers = neutron.ipam_drivers = vmware_nsxv_ipam = vmware_nsx.services.ipam.nsx_v.driver:NsxvIpamDriver vmware_nsxv3_ipam = vmware_nsx.services.ipam.nsx_v3.driver:Nsxv3IpamDriver + vmware_nsxtvd_ipam = vmware_nsx.services.ipam.nsx_tvd.driver:NsxTvdIpamDriver vmware_nsx.extension_drivers = vmware_nsxv_dns = vmware_nsx.extension_drivers.dns_integration:DNSExtensionDriverNSXv vmware_nsxv3_dns = vmware_nsx.extension_drivers.dns_integration:DNSExtensionDriverNSXv3 diff --git a/vmware_nsx/services/ipam/common/driver.py b/vmware_nsx/services/ipam/common/driver.py index c990eebbcf..c9d84afe49 100644 --- a/vmware_nsx/services/ipam/common/driver.py +++ b/vmware_nsx/services/ipam/common/driver.py @@ -16,15 +16,21 @@ import abc +import six + +from oslo_log import log as logging + from neutron.ipam import driver as ipam_base from neutron.ipam.drivers.neutrondb_ipam import driver as neutron_driver from neutron.ipam import exceptions as ipam_exc from neutron.ipam import requests as ipam_req from neutron.ipam import subnet_alloc from neutron_lib.plugins import directory -import six from vmware_nsx.db import db as nsx_db +from vmware_nsx.extensions import projectpluginmap + +LOG = logging.getLogger(__name__) @six.add_metaclass(abc.ABCMeta) @@ -33,6 +39,30 @@ class NsxIpamBase(object): def get_core_plugin(cls): return directory.get_plugin() + @property + def _nsxlib(self): + p = self.get_core_plugin() + if p.is_tvd_plugin(): + # get the NSX-T sub-plugin + p = p.get_plugin_by_type( + projectpluginmap.NsxPlugins.NSX_T) + elif p.plugin_type() != projectpluginmap.NsxPlugins.NSX_T: + # Non NSX-T plugin + return + return p.nsxlib + + @property + def _vcns(self): + p = self.get_core_plugin() + if p.is_tvd_plugin(): + # get the NSX-V sub-plugin + p = p.get_plugin_by_type( + projectpluginmap.NsxPlugins.NSX_V) + elif p.plugin_type() != projectpluginmap.NsxPlugins.NSX_V: + # Non NSX-V plugin + return + return p.nsx_v.vcns + @classmethod def _fetch_subnet(cls, context, id): p = cls.get_core_plugin() diff --git a/vmware_nsx/services/ipam/nsx_tvd/__init__.py b/vmware_nsx/services/ipam/nsx_tvd/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/vmware_nsx/services/ipam/nsx_tvd/driver.py b/vmware_nsx/services/ipam/nsx_tvd/driver.py new file mode 100644 index 0000000000..5efeaf1feb --- /dev/null +++ b/vmware_nsx/services/ipam/nsx_tvd/driver.py @@ -0,0 +1,88 @@ +# Copyright 2016 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 oslo_log import log as logging + +from neutron.ipam import exceptions as ipam_exc +from neutron.ipam import subnet_alloc + +from vmware_nsx.extensions import projectpluginmap +from vmware_nsx.plugins.nsx import utils as tvd_utils +from vmware_nsx.services.ipam.common import driver as common_driver +from vmware_nsx.services.ipam.nsx_v import driver as v_driver +from vmware_nsx.services.ipam.nsx_v3 import driver as t_driver + +LOG = logging.getLogger(__name__) + + +class NsxTvdIpamDriver(subnet_alloc.SubnetAllocator, + common_driver.NsxIpamBase): + """IPAM Driver For NSX-TVD plugin.""" + + def __init__(self, subnetpool, context): + super(NsxTvdIpamDriver, self).__init__(subnetpool, context) + # initialize the different drivers + self.drivers = {} + try: + self.drivers[projectpluginmap.NsxPlugins.NSX_T] = ( + t_driver.Nsxv3IpamDriver(subnetpool, context)) + except Exception as e: + LOG.warning("NsxTvdIpamDriver failed to initialize the NSX-T " + "driver %s", e) + self.drivers[projectpluginmap.NsxPlugins.NSX_T] = None + try: + self.drivers[projectpluginmap.NsxPlugins.NSX_V] = ( + v_driver.NsxvIpamDriver(subnetpool, context)) + except Exception as e: + LOG.warning("NsxTvdIpamDriver failed to initialize the NSX-V " + "driver %s", e) + self.drivers[projectpluginmap.NsxPlugins.NSX_V] = None + + def get_T_driver(self): + return self.drivers[projectpluginmap.NsxPlugins.NSX_T] + + def get_V_driver(self): + return self.drivers[projectpluginmap.NsxPlugins.NSX_V] + + def _get_driver_for_project(self, project): + plugin_type = tvd_utils.get_tvd_plugin_type_for_project(project) + if not self.drivers.get(plugin_type): + LOG.error("Project %(project)s with plugin %(plugin)s has no " + "support for IPAM", {'project': project, + 'plugin': plugin_type}) + raise ipam_exc.IpamValueInvalid( + msg="IPAM driver not found") + return self.drivers[plugin_type] + + def allocate_subnet(self, subnet_request): + d = self._get_driver_for_project(subnet_request.tenant_id) + return d.allocate_subnet(subnet_request) + + def update_subnet(self, subnet_request): + d = self._get_driver_for_project(subnet_request.tenant_id) + return d.update_subnet(subnet_request) + + def remove_subnet(self, subnet_id): + d = self._get_driver_for_project(self._context.tenant_id) + return d.remove_subnet(subnet_id) + + def get_subnet(self, subnet_id): + d = self._get_driver_for_project(self._context.tenant_id) + return d.get_subnet(subnet_id) + + def get_subnet_request_factory(self): + d = self._get_driver_for_project(self._context.tenant_id) + return d.get_subnet_request_factory() diff --git a/vmware_nsx/services/ipam/nsx_v/driver.py b/vmware_nsx/services/ipam/nsx_v/driver.py index d195db11bc..5f1bf7e76b 100644 --- a/vmware_nsx/services/ipam/nsx_v/driver.py +++ b/vmware_nsx/services/ipam/nsx_v/driver.py @@ -33,15 +33,7 @@ from vmware_nsx.services.ipam.common import driver as common LOG = logging.getLogger(__name__) -class NsxVIpamBase(common.NsxIpamBase): - - @property - def _vcns(self): - p = self.get_core_plugin() - return p.nsx_v.vcns - - -class NsxvIpamDriver(common.NsxAbstractIpamDriver, NsxVIpamBase): +class NsxvIpamDriver(common.NsxAbstractIpamDriver, common.NsxIpamBase): """IPAM Driver For NSX-V external & provider networks.""" def _is_ext_or_provider_net(self, subnet_request): @@ -122,7 +114,7 @@ class NsxvIpamDriver(common.NsxAbstractIpamDriver, NsxVIpamBase): pass -class NsxvIpamSubnet(common.NsxAbstractIpamSubnet, NsxVIpamBase): +class NsxvIpamSubnet(common.NsxAbstractIpamSubnet, common.NsxIpamBase): """Manage IP addresses for the NSX-V IPAM driver.""" def _get_vcns_error_code(self, e): diff --git a/vmware_nsx/services/ipam/nsx_v3/driver.py b/vmware_nsx/services/ipam/nsx_v3/driver.py index 4f9ce3b571..c05ed8761f 100644 --- a/vmware_nsx/services/ipam/nsx_v3/driver.py +++ b/vmware_nsx/services/ipam/nsx_v3/driver.py @@ -30,11 +30,11 @@ LOG = logging.getLogger(__name__) class Nsxv3IpamDriver(common.NsxAbstractIpamDriver): - """IPAM Driver For NSX-V3 external & provider networks.""" + """IPAM Driver For NSX-V3 networks.""" def __init__(self, subnetpool, context): super(Nsxv3IpamDriver, self).__init__(subnetpool, context) - self.nsxlib_ipam = self.get_core_plugin().nsxlib.ip_pool + self.nsxlib_ipam = self._nsxlib.ip_pool # Mark which updates to the pool are supported self.support_update_gateway = True @@ -133,7 +133,7 @@ class Nsxv3IpamSubnet(common.NsxAbstractIpamSubnet): def __init__(self, subnet_id, nsx_pool_id, ctx, tenant_id): super(Nsxv3IpamSubnet, self).__init__( subnet_id, nsx_pool_id, ctx, tenant_id) - self.nsxlib_ipam = self.get_core_plugin().nsxlib.ip_pool + self.nsxlib_ipam = self._nsxlib.ip_pool def backend_allocate(self, address_request): try: