summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJenkins <jenkins@review.openstack.org>2013-02-01 06:41:00 +0000
committerGerrit Code Review <review@openstack.org>2013-02-01 06:41:00 +0000
commitc421d775ee3052d1af4c08b8ff81f6877ca8b1a8 (patch)
tree31d9048bec98176668063b468ed0f202eb3930ec
parent967807f898ec0f6b467045ca3f80feb6967d4177 (diff)
parentdd5f2c82d7d23a3bac3aabaa8cc58a10d4b70fcf (diff)
downloadnova-c421d775ee3052d1af4c08b8ff81f6877ca8b1a8.tar.gz
nova-c421d775ee3052d1af4c08b8ff81f6877ca8b1a8.tar.xz
nova-c421d775ee3052d1af4c08b8ff81f6877ca8b1a8.zip
Merge "Split floating ip functionality into new file."
-rwxr-xr-xbin/nova-manage2
-rw-r--r--nova/api/openstack/compute/contrib/floating_ips_bulk.py2
-rw-r--r--nova/network/floating_ips.py662
-rw-r--r--nova/network/manager.py632
-rw-r--r--nova/network/quantumv2/api.py2
-rw-r--r--nova/tests/network/test_manager.py11
6 files changed, 675 insertions, 636 deletions
diff --git a/bin/nova-manage b/bin/nova-manage
index 90d191eca..82edf7389 100755
--- a/bin/nova-manage
+++ b/bin/nova-manage
@@ -98,7 +98,7 @@ CONF.import_opt('multi_host', 'nova.network.manager')
CONF.import_opt('network_size', 'nova.network.manager')
CONF.import_opt('vlan_start', 'nova.network.manager')
CONF.import_opt('vpn_start', 'nova.network.manager')
-CONF.import_opt('default_floating_pool', 'nova.network.manager')
+CONF.import_opt('default_floating_pool', 'nova.network.floating_ips')
CONF.import_opt('public_interface', 'nova.network.linux_net')
QUOTAS = quota.QUOTAS
diff --git a/nova/api/openstack/compute/contrib/floating_ips_bulk.py b/nova/api/openstack/compute/contrib/floating_ips_bulk.py
index db506a15d..11ab0ec69 100644
--- a/nova/api/openstack/compute/contrib/floating_ips_bulk.py
+++ b/nova/api/openstack/compute/contrib/floating_ips_bulk.py
@@ -25,7 +25,7 @@ from nova.openstack.common import cfg
from nova.openstack.common import log as logging
CONF = cfg.CONF
-CONF.import_opt('default_floating_pool', 'nova.network.manager')
+CONF.import_opt('default_floating_pool', 'nova.network.floating_ips')
CONF.import_opt('public_interface', 'nova.network.linux_net')
diff --git a/nova/network/floating_ips.py b/nova/network/floating_ips.py
new file mode 100644
index 000000000..6d8606113
--- /dev/null
+++ b/nova/network/floating_ips.py
@@ -0,0 +1,662 @@
+# vim: tabstop=4 shiftwidth=4 softtabstop=4
+
+# Copyright (c) 2011 X.commerce, a business unit of eBay Inc.
+# Copyright 2010 United States Government as represented by the
+# Administrator of the National Aeronautics and Space Administration.
+# 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 nova import context
+from nova import exception
+from nova.openstack.common import cfg
+from nova.openstack.common import excutils
+from nova.openstack.common import lockutils
+from nova.openstack.common import log as logging
+from nova.openstack.common.notifier import api as notifier
+from nova.openstack.common.rpc import common as rpc_common
+from nova import quota
+
+LOG = logging.getLogger(__name__)
+
+QUOTAS = quota.QUOTAS
+
+floating_opts = [
+ cfg.StrOpt('default_floating_pool',
+ default='nova',
+ help='Default pool for floating ips'),
+ cfg.BoolOpt('auto_assign_floating_ip',
+ default=False,
+ help='Autoassigning floating ip to VM'),
+]
+
+CONF = cfg.CONF
+CONF.register_opts(floating_opts)
+CONF.import_opt('public_interface', 'nova.network.linux_net')
+
+
+class FloatingIP(object):
+ """Mixin class for adding floating IP functionality to a manager."""
+
+ servicegroup_api = None
+
+ def init_host_floating_ips(self):
+ """Configures floating ips owned by host."""
+
+ admin_context = context.get_admin_context()
+ try:
+ floating_ips = self.db.floating_ip_get_all_by_host(admin_context,
+ self.host)
+ except exception.NotFound:
+ return
+
+ for floating_ip in floating_ips:
+ fixed_ip_id = floating_ip.get('fixed_ip_id')
+ if fixed_ip_id:
+ try:
+ fixed_ip = self.db.fixed_ip_get(admin_context,
+ fixed_ip_id,
+ get_network=True)
+ except exception.FixedIpNotFound:
+ msg = _('Fixed ip %(fixed_ip_id)s not found') % locals()
+ LOG.debug(msg)
+ continue
+ interface = CONF.public_interface or floating_ip['interface']
+ try:
+ self.l3driver.add_floating_ip(floating_ip['address'],
+ fixed_ip['address'],
+ interface,
+ fixed_ip['network'])
+ except exception.ProcessExecutionError:
+ LOG.debug(_('Interface %(interface)s not found'), locals())
+ raise exception.NoFloatingIpInterface(interface=interface)
+
+ def allocate_for_instance(self, context, **kwargs):
+ """Handles allocating the floating IP resources for an instance.
+
+ calls super class allocate_for_instance() as well
+
+ rpc.called by network_api
+ """
+ instance_id = kwargs.get('instance_id')
+ instance_uuid = kwargs.get('instance_uuid')
+ project_id = kwargs.get('project_id')
+ requested_networks = kwargs.get('requested_networks')
+ LOG.debug(_("floating IP allocation for instance |%s|"),
+ instance_uuid=instance_uuid, context=context)
+ # call the next inherited class's allocate_for_instance()
+ # which is currently the NetworkManager version
+ # do this first so fixed ip is already allocated
+ nw_info = super(FloatingIP, self).allocate_for_instance(context,
+ **kwargs)
+ if CONF.auto_assign_floating_ip:
+ # allocate a floating ip
+ floating_address = self.allocate_floating_ip(context, project_id,
+ True)
+ # set auto_assigned column to true for the floating ip
+ self.db.floating_ip_set_auto_assigned(context, floating_address)
+
+ # get the first fixed address belonging to the instance
+ fixed_ips = nw_info.fixed_ips()
+ fixed_address = fixed_ips[0]['address']
+
+ # associate the floating ip to fixed_ip
+ self.associate_floating_ip(context,
+ floating_address,
+ fixed_address,
+ affect_auto_assigned=True)
+
+ # create a fresh set of network info that contains the floating ip
+ nw_info = self.get_instance_nw_info(context, **kwargs)
+
+ return nw_info
+
+ def deallocate_for_instance(self, context, **kwargs):
+ """Handles deallocating floating IP resources for an instance.
+
+ calls super class deallocate_for_instance() as well.
+
+ rpc.called by network_api
+ """
+ instance_id = kwargs.get('instance_id')
+
+ # NOTE(francois.charlier): in some cases the instance might be
+ # deleted before the IPs are released, so we need to get deleted
+ # instances too
+ instance = self.db.instance_get(
+ context.elevated(read_deleted='yes'), instance_id)
+
+ try:
+ fixed_ips = self.db.fixed_ip_get_by_instance(context,
+ instance['uuid'])
+ except exception.FixedIpNotFoundForInstance:
+ fixed_ips = []
+ # add to kwargs so we can pass to super to save a db lookup there
+ kwargs['fixed_ips'] = fixed_ips
+ for fixed_ip in fixed_ips:
+ fixed_id = fixed_ip['id']
+ floating_ips = self.db.floating_ip_get_by_fixed_ip_id(context,
+ fixed_id)
+ # disassociate floating ips related to fixed_ip
+ for floating_ip in floating_ips:
+ address = floating_ip['address']
+ try:
+ self.disassociate_floating_ip(context,
+ address,
+ affect_auto_assigned=True)
+ except exception.FloatingIpNotAssociated:
+ LOG.exception(_("Floating IP is not associated. Ignore."))
+ # deallocate if auto_assigned
+ if floating_ip['auto_assigned']:
+ self.deallocate_floating_ip(context, address,
+ affect_auto_assigned=True)
+
+ # call the next inherited class's deallocate_for_instance()
+ # which is currently the NetworkManager version
+ # call this after so floating IPs are handled first
+ super(FloatingIP, self).deallocate_for_instance(context, **kwargs)
+
+ def _floating_ip_owned_by_project(self, context, floating_ip):
+ """Raises if floating ip does not belong to project."""
+ if context.is_admin:
+ return
+
+ if floating_ip['project_id'] != context.project_id:
+ if floating_ip['project_id'] is None:
+ LOG.warn(_('Address |%(address)s| is not allocated'),
+ {'address': floating_ip['address']})
+ raise exception.NotAuthorized()
+ else:
+ LOG.warn(_('Address |%(address)s| is not allocated to your '
+ 'project |%(project)s|'),
+ {'address': floating_ip['address'],
+ 'project': context.project_id})
+ raise exception.NotAuthorized()
+
+ def allocate_floating_ip(self, context, project_id, auto_assigned=False,
+ pool=None):
+ """Gets a floating ip from the pool."""
+ # NOTE(tr3buchet): all network hosts in zone now use the same pool
+ pool = pool or CONF.default_floating_pool
+ use_quota = not auto_assigned
+
+ # Check the quota; can't put this in the API because we get
+ # called into from other places
+ try:
+ if use_quota:
+ reservations = QUOTAS.reserve(context, floating_ips=1)
+ except exception.OverQuota:
+ pid = context.project_id
+ LOG.warn(_("Quota exceeded for %(pid)s, tried to allocate "
+ "floating IP") % locals())
+ raise exception.FloatingIpLimitExceeded()
+
+ try:
+ floating_ip = self.db.floating_ip_allocate_address(context,
+ project_id,
+ pool)
+ payload = dict(project_id=project_id, floating_ip=floating_ip)
+ notifier.notify(context,
+ notifier.publisher_id("network"),
+ 'network.floating_ip.allocate',
+ notifier.INFO, payload)
+
+ # Commit the reservations
+ if use_quota:
+ QUOTAS.commit(context, reservations)
+ except Exception:
+ with excutils.save_and_reraise_exception():
+ if use_quota:
+ QUOTAS.rollback(context, reservations)
+
+ return floating_ip
+
+ @rpc_common.client_exceptions(exception.FloatingIpNotFoundForAddress)
+ def deallocate_floating_ip(self, context, address,
+ affect_auto_assigned=False):
+ """Returns a floating ip to the pool."""
+ floating_ip = self.db.floating_ip_get_by_address(context, address)
+
+ # handle auto_assigned
+ if not affect_auto_assigned and floating_ip.get('auto_assigned'):
+ return
+ use_quota = not floating_ip.get('auto_assigned')
+
+ # make sure project owns this floating ip (allocated)
+ self._floating_ip_owned_by_project(context, floating_ip)
+
+ # make sure floating ip is not associated
+ if floating_ip['fixed_ip_id']:
+ floating_address = floating_ip['address']
+ raise exception.FloatingIpAssociated(address=floating_address)
+
+ # clean up any associated DNS entries
+ self._delete_all_entries_for_ip(context,
+ floating_ip['address'])
+ payload = dict(project_id=floating_ip['project_id'],
+ floating_ip=floating_ip['address'])
+ notifier.notify(context,
+ notifier.publisher_id("network"),
+ 'network.floating_ip.deallocate',
+ notifier.INFO, payload=payload)
+
+ # Get reservations...
+ try:
+ if use_quota:
+ reservations = QUOTAS.reserve(context, floating_ips=-1)
+ else:
+ reservations = None
+ except Exception:
+ reservations = None
+ LOG.exception(_("Failed to update usages deallocating "
+ "floating IP"))
+
+ self.db.floating_ip_deallocate(context, address)
+
+ # Commit the reservations
+ if reservations:
+ QUOTAS.commit(context, reservations)
+
+ @rpc_common.client_exceptions(exception.FloatingIpNotFoundForAddress)
+ def associate_floating_ip(self, context, floating_address, fixed_address,
+ affect_auto_assigned=False):
+ """Associates a floating ip with a fixed ip.
+
+ Makes sure everything makes sense then calls _associate_floating_ip,
+ rpc'ing to correct host if i'm not it.
+
+ Access to the floating_address is verified but access to the
+ fixed_address is not verified. This assumes that that the calling
+ side has already verified that the fixed_address is legal by
+ checking access to the instance.
+ """
+ floating_ip = self.db.floating_ip_get_by_address(context,
+ floating_address)
+ # handle auto_assigned
+ if not affect_auto_assigned and floating_ip.get('auto_assigned'):
+ return
+
+ # make sure project owns this floating ip (allocated)
+ self._floating_ip_owned_by_project(context, floating_ip)
+
+ # disassociate any already associated
+ orig_instance_uuid = None
+ if floating_ip['fixed_ip_id']:
+ # find previously associated instance
+ fixed_ip = self.db.fixed_ip_get(context,
+ floating_ip['fixed_ip_id'])
+ if fixed_ip['address'] == fixed_address:
+ # NOTE(vish): already associated to this address
+ return
+ orig_instance_uuid = fixed_ip['instance_uuid']
+
+ self.disassociate_floating_ip(context, floating_address)
+
+ fixed_ip = self.db.fixed_ip_get_by_address(context, fixed_address)
+
+ # send to correct host, unless i'm the correct host
+ network = self.db.network_get(context.elevated(),
+ fixed_ip['network_id'])
+ if network['multi_host']:
+ instance = self.db.instance_get_by_uuid(context,
+ fixed_ip['instance_uuid'])
+ host = instance['host']
+ else:
+ host = network['host']
+
+ interface = floating_ip.get('interface')
+ if host == self.host:
+ # i'm the correct host
+ self._associate_floating_ip(context, floating_address,
+ fixed_address, interface,
+ fixed_ip['instance_uuid'])
+ else:
+ # send to correct host
+ self.network_rpcapi._associate_floating_ip(context,
+ floating_address, fixed_address, interface, host,
+ fixed_ip['instance_uuid'])
+
+ return orig_instance_uuid
+
+ def _associate_floating_ip(self, context, floating_address, fixed_address,
+ interface, instance_uuid):
+ """Performs db and driver calls to associate floating ip & fixed ip."""
+ interface = CONF.public_interface or interface
+
+ @lockutils.synchronized(unicode(floating_address), 'nova-')
+ def do_associate():
+ # associate floating ip
+ fixed = self.db.floating_ip_fixed_ip_associate(context,
+ floating_address,
+ fixed_address,
+ self.host)
+ if not fixed:
+ # NOTE(vish): ip was already associated
+ return
+ try:
+ # gogo driver time
+ self.l3driver.add_floating_ip(floating_address, fixed_address,
+ interface, fixed['network'])
+ except exception.ProcessExecutionError as e:
+ self.db.floating_ip_disassociate(context, floating_address)
+ if "Cannot find device" in str(e):
+ LOG.error(_('Interface %(interface)s not found'), locals())
+ raise exception.NoFloatingIpInterface(interface=interface)
+
+ payload = dict(project_id=context.project_id,
+ instance_id=instance_uuid,
+ floating_ip=floating_address)
+ notifier.notify(context,
+ notifier.publisher_id("network"),
+ 'network.floating_ip.associate',
+ notifier.INFO, payload=payload)
+ do_associate()
+
+ @rpc_common.client_exceptions(exception.FloatingIpNotFoundForAddress)
+ def disassociate_floating_ip(self, context, address,
+ affect_auto_assigned=False):
+ """Disassociates a floating ip from its fixed ip.
+
+ Makes sure everything makes sense then calls _disassociate_floating_ip,
+ rpc'ing to correct host if i'm not it.
+ """
+ floating_ip = self.db.floating_ip_get_by_address(context, address)
+
+ # handle auto assigned
+ if not affect_auto_assigned and floating_ip.get('auto_assigned'):
+ raise exception.CannotDisassociateAutoAssignedFloatingIP()
+
+ # make sure project owns this floating ip (allocated)
+ self._floating_ip_owned_by_project(context, floating_ip)
+
+ # make sure floating ip is associated
+ if not floating_ip.get('fixed_ip_id'):
+ floating_address = floating_ip['address']
+ raise exception.FloatingIpNotAssociated(address=floating_address)
+
+ fixed_ip = self.db.fixed_ip_get(context, floating_ip['fixed_ip_id'])
+
+ # send to correct host, unless i'm the correct host
+ network = self.db.network_get(context.elevated(),
+ fixed_ip['network_id'])
+ interface = floating_ip.get('interface')
+ if network['multi_host']:
+ instance = self.db.instance_get_by_uuid(context,
+ fixed_ip['instance_uuid'])
+ service = self.db.service_get_by_host_and_topic(
+ context.elevated(), instance['host'], 'network')
+ if service and self.servicegroup_api.service_is_up(service):
+ host = instance['host']
+ else:
+ # NOTE(vish): if the service is down just deallocate the data
+ # locally. Set the host to local so the call will
+ # not go over rpc and set interface to None so the
+ # teardown in the driver does not happen.
+ host = self.host
+ interface = None
+ else:
+ host = network['host']
+
+ if host == self.host:
+ # i'm the correct host
+ self._disassociate_floating_ip(context, address, interface,
+ fixed_ip['instance_uuid'])
+ else:
+ # send to correct host
+ self.network_rpcapi._disassociate_floating_ip(context, address,
+ interface, host, fixed_ip['instance_uuid'])
+
+ def _disassociate_floating_ip(self, context, address, interface,
+ instance_uuid):
+ """Performs db and driver calls to disassociate floating ip."""
+ interface = CONF.public_interface or interface
+
+ @lockutils.synchronized(unicode(address), 'nova-')
+ def do_disassociate():
+ # NOTE(vish): Note that we are disassociating in the db before we
+ # actually remove the ip address on the host. We are
+ # safe from races on this host due to the decorator,
+ # but another host might grab the ip right away. We
+ # don't worry about this case because the minuscule
+ # window where the ip is on both hosts shouldn't cause
+ # any problems.
+ fixed = self.db.floating_ip_disassociate(context, address)
+
+ if not fixed:
+ # NOTE(vish): ip was already disassociated
+ return
+ if interface:
+ # go go driver time
+ self.l3driver.remove_floating_ip(address, fixed['address'],
+ interface, fixed['network'])
+ payload = dict(project_id=context.project_id,
+ instance_id=instance_uuid,
+ floating_ip=address)
+ notifier.notify(context,
+ notifier.publisher_id("network"),
+ 'network.floating_ip.disassociate',
+ notifier.INFO, payload=payload)
+ do_disassociate()
+
+ @rpc_common.client_exceptions(exception.FloatingIpNotFound)
+ def get_floating_ip(self, context, id):
+ """Returns a floating IP as a dict."""
+ # NOTE(vish): This is no longer used but can't be removed until
+ # we major version the network_rpcapi.
+ return dict(self.db.floating_ip_get(context, id).iteritems())
+
+ def get_floating_pools(self, context):
+ """Returns list of floating pools."""
+ # NOTE(maurosr) This method should be removed in future, replaced by
+ # get_floating_ip_pools. See bug #1091668
+ return self.get_floating_ip_pools(context)
+
+ def get_floating_ip_pools(self, context):
+ """Returns list of floating ip pools."""
+ # NOTE(vish): This is no longer used but can't be removed until
+ # we major version the network_rpcapi.
+ pools = self.db.floating_ip_get_pools(context)
+ return [dict(pool.iteritems()) for pool in pools]
+
+ def get_floating_ip_by_address(self, context, address):
+ """Returns a floating IP as a dict."""
+ # NOTE(vish): This is no longer used but can't be removed until
+ # we major version the network_rpcapi.
+ return dict(self.db.floating_ip_get_by_address(context,
+ address).iteritems())
+
+ def get_floating_ips_by_project(self, context):
+ """Returns the floating IPs allocated to a project."""
+ # NOTE(vish): This is no longer used but can't be removed until
+ # we major version the network_rpcapi.
+ ips = self.db.floating_ip_get_all_by_project(context,
+ context.project_id)
+ return [dict(ip.iteritems()) for ip in ips]
+
+ def get_floating_ips_by_fixed_address(self, context, fixed_address):
+ """Returns the floating IPs associated with a fixed_address."""
+ # NOTE(vish): This is no longer used but can't be removed until
+ # we major version the network_rpcapi.
+ floating_ips = self.db.floating_ip_get_by_fixed_address(context,
+ fixed_address)
+ return [floating_ip['address'] for floating_ip in floating_ips]
+
+ def _is_stale_floating_ip_address(self, context, floating_ip):
+ try:
+ self._floating_ip_owned_by_project(context, floating_ip)
+ except exception.NotAuthorized:
+ return True
+ return False if floating_ip.get('fixed_ip_id') else True
+
+ def migrate_instance_start(self, context, instance_uuid,
+ floating_addresses,
+ rxtx_factor=None, project_id=None,
+ source=None, dest=None):
+ # We only care if floating_addresses are provided and we're
+ # switching hosts
+ if not floating_addresses or (source and source == dest):
+ return
+
+ LOG.info(_("Starting migration network for instance"
+ " %(instance_uuid)s"), locals())
+ for address in floating_addresses:
+ floating_ip = self.db.floating_ip_get_by_address(context,
+ address)
+
+ if self._is_stale_floating_ip_address(context, floating_ip):
+ LOG.warn(_("Floating ip address |%(address)s| no longer "
+ "belongs to instance %(instance_uuid)s. Will not"
+ "migrate it "), locals())
+ continue
+
+ interface = CONF.public_interface or floating_ip['interface']
+ fixed_ip = self.db.fixed_ip_get(context,
+ floating_ip['fixed_ip_id'],
+ get_network=True)
+ self.l3driver.remove_floating_ip(floating_ip['address'],
+ fixed_ip['address'],
+ interface,
+ fixed_ip['network'])
+
+ # NOTE(wenjianhn): Make this address will not be bound to public
+ # interface when restarts nova-network on dest compute node
+ self.db.floating_ip_update(context,
+ floating_ip['address'],
+ {'host': None})
+
+ def migrate_instance_finish(self, context, instance_uuid,
+ floating_addresses, host=None,
+ rxtx_factor=None, project_id=None,
+ source=None, dest=None):
+ # We only care if floating_addresses are provided and we're
+ # switching hosts
+ if host and not dest:
+ dest = host
+ if not floating_addresses or (source and source == dest):
+ return
+
+ LOG.info(_("Finishing migration network for instance"
+ " %(instance_uuid)s"), locals())
+
+ for address in floating_addresses:
+ floating_ip = self.db.floating_ip_get_by_address(context,
+ address)
+
+ if self._is_stale_floating_ip_address(context, floating_ip):
+ LOG.warn(_("Floating ip address |%(address)s| no longer "
+ "belongs to instance %(instance_uuid)s. Will not"
+ "setup it."), locals())
+ continue
+
+ self.db.floating_ip_update(context,
+ floating_ip['address'],
+ {'host': dest})
+
+ interface = CONF.public_interface or floating_ip['interface']
+ fixed_ip = self.db.fixed_ip_get(context,
+ floating_ip['fixed_ip_id'],
+ get_network=True)
+ self.l3driver.add_floating_ip(floating_ip['address'],
+ fixed_ip['address'],
+ interface,
+ fixed_ip['network'])
+
+ def _prepare_domain_entry(self, context, domain):
+ domainref = self.db.dnsdomain_get(context, domain)
+ scope = domainref['scope']
+ if scope == 'private':
+ av_zone = domainref['availability_zone']
+ this_domain = {'domain': domain,
+ 'scope': scope,
+ 'availability_zone': av_zone}
+ else:
+ project = domainref['project_id']
+ this_domain = {'domain': domain,
+ 'scope': scope,
+ 'project': project}
+ return this_domain
+
+ def get_dns_domains(self, context):
+ domains = []
+
+ db_domain_list = self.db.dnsdomain_list(context)
+ floating_driver_domain_list = self.floating_dns_manager.get_domains()
+ instance_driver_domain_list = self.instance_dns_manager.get_domains()
+
+ for db_domain in db_domain_list:
+ if (db_domain in floating_driver_domain_list or
+ db_domain in instance_driver_domain_list):
+ domain_entry = self._prepare_domain_entry(context,
+ db_domain)
+ if domain_entry:
+ domains.append(domain_entry)
+ else:
+ LOG.warn(_('Database inconsistency: DNS domain |%s| is '
+ 'registered in the Nova db but not visible to '
+ 'either the floating or instance DNS driver. It '
+ 'will be ignored.'), db_domain)
+
+ return domains
+
+ def add_dns_entry(self, context, address, name, dns_type, domain):
+ self.floating_dns_manager.create_entry(name, address,
+ dns_type, domain)
+
+ def modify_dns_entry(self, context, address, name, domain):
+ self.floating_dns_manager.modify_address(name, address,
+ domain)
+
+ def delete_dns_entry(self, context, name, domain):
+ self.floating_dns_manager.delete_entry(name, domain)
+
+ def _delete_all_entries_for_ip(self, context, address):
+ domain_list = self.get_dns_domains(context)
+ for domain in domain_list:
+ names = self.get_dns_entries_by_address(context,
+ address,
+ domain['domain'])
+ for name in names:
+ self.delete_dns_entry(context, name, domain['domain'])
+
+ def get_dns_entries_by_address(self, context, address, domain):
+ return self.floating_dns_manager.get_entries_by_address(address,
+ domain)
+
+ def get_dns_entries_by_name(self, context, name, domain):
+ return self.floating_dns_manager.get_entries_by_name(name,
+ domain)
+
+ def create_private_dns_domain(self, context, domain, av_zone):
+ self.db.dnsdomain_register_for_zone(context, domain, av_zone)
+ try:
+ self.instance_dns_manager.create_domain(domain)
+ except exception.FloatingIpDNSExists:
+ LOG.warn(_('Domain |%(domain)s| already exists, '
+ 'changing zone to |%(av_zone)s|.'),
+ {'domain': domain, 'av_zone': av_zone})
+
+ def create_public_dns_domain(self, context, domain, project):
+ self.db.dnsdomain_register_for_project(context, domain, project)
+ try:
+ self.floating_dns_manager.create_domain(domain)
+ except exception.FloatingIpDNSExists:
+ LOG.warn(_('Domain |%(domain)s| already exists, '
+ 'changing project to |%(project)s|.'),
+ {'domain': domain, 'project': project})
+
+ def delete_dns_domain(self, context, domain):
+ self.db.dnsdomain_unregister(context, domain)
+ self.floating_dns_manager.delete_domain(domain)
+
+ def _get_project_for_domain(self, context, domain):
+ return self.db.dnsdomain_project(context, domain)
diff --git a/nova/network/manager.py b/nova/network/manager.py
index f57bb197b..161bf421b 100644
--- a/nova/network/manager.py
+++ b/nova/network/manager.py
@@ -34,7 +34,6 @@ topologies. All of the network commands are issued to a subclass of
:vpn_start: First Vpn port for private networks
:cnt_vpn_clients: Number of addresses reserved for vpn clients
:network_size: Number of addresses in each private subnet
-:floating_range: Floating IP address block
:fixed_range: Fixed IP address block
:fixed_ip_disassociate_timeout: Seconds after which a deallocated ip
is disassociated
@@ -59,26 +58,22 @@ from nova import ipv6
from nova import manager
from nova.network import api as network_api
from nova.network import driver
+from nova.network import floating_ips
from nova.network import model as network_model
from nova.network import rpcapi as network_rpcapi
from nova.openstack.common import cfg
-from nova.openstack.common import excutils
from nova.openstack.common import importutils
from nova.openstack.common import jsonutils
from nova.openstack.common import lockutils
from nova.openstack.common import log as logging
-from nova.openstack.common.notifier import api as notifier
-from nova.openstack.common.rpc import common as rpc_common
from nova.openstack.common import timeutils
from nova.openstack.common import uuidutils
-from nova import quota
from nova import servicegroup
from nova import utils
LOG = logging.getLogger(__name__)
-QUOTAS = quota.QUOTAS
network_opts = [
cfg.StrOpt('flat_network_bridge',
@@ -114,12 +109,6 @@ network_opts = [
cfg.IntOpt('network_size',
default=256,
help='Number of addresses in each private subnet'),
- cfg.StrOpt('floating_range',
- default='4.4.4.0/24',
- help='Floating IP address block'),
- cfg.StrOpt('default_floating_pool',
- default='nova',
- help='Default pool for floating ips'),
cfg.StrOpt('fixed_range',
default='10.0.0.0/8',
help='Fixed IP address block'),
@@ -141,9 +130,6 @@ network_opts = [
cfg.IntOpt('create_unique_mac_address_attempts',
default=5,
help='Number of attempts to create unique mac address'),
- cfg.BoolOpt('auto_assign_floating_ip',
- default=False,
- help='Autoassigning floating ip to VM'),
cfg.BoolOpt('fake_network',
default=False,
help='If passed, use fake network devices and addresses'),
@@ -274,617 +260,6 @@ class RPCAllocateFixedIP(object):
self.network_rpcapi.deallocate_fixed_ip(context, address, host)
-class FloatingIP(object):
- """Mixin class for adding floating IP functionality to a manager."""
-
- servicegroup_api = None
-
- def init_host_floating_ips(self):
- """Configures floating ips owned by host."""
-
- admin_context = context.get_admin_context()
- try:
- floating_ips = self.db.floating_ip_get_all_by_host(admin_context,
- self.host)
- except exception.NotFound:
- return
-
- for floating_ip in floating_ips:
- fixed_ip_id = floating_ip.get('fixed_ip_id')
- if fixed_ip_id:
- try:
- fixed_ip = self.db.fixed_ip_get(admin_context,
- fixed_ip_id,
- get_network=True)
- except exception.FixedIpNotFound:
- msg = _('Fixed ip %(fixed_ip_id)s not found') % locals()
- LOG.debug(msg)
- continue
- interface = CONF.public_interface or floating_ip['interface']
- try:
- self.l3driver.add_floating_ip(floating_ip['address'],
- fixed_ip['address'],
- interface,
- fixed_ip['network'])
- except exception.ProcessExecutionError:
- LOG.debug(_('Interface %(interface)s not found'), locals())
- raise exception.NoFloatingIpInterface(interface=interface)
-
- def allocate_for_instance(self, context, **kwargs):
- """Handles allocating the floating IP resources for an instance.
-
- calls super class allocate_for_instance() as well
-
- rpc.called by network_api
- """
- instance_id = kwargs.get('instance_id')
- instance_uuid = kwargs.get('instance_uuid')
- project_id = kwargs.get('project_id')
- requested_networks = kwargs.get('requested_networks')
- LOG.debug(_("floating IP allocation for instance |%s|"),
- instance_uuid=instance_uuid, context=context)
- # call the next inherited class's allocate_for_instance()
- # which is currently the NetworkManager version
- # do this first so fixed ip is already allocated
- nw_info = super(FloatingIP, self).allocate_for_instance(context,
- **kwargs)
- if CONF.auto_assign_floating_ip:
- # allocate a floating ip
- floating_address = self.allocate_floating_ip(context, project_id,
- True)
- # set auto_assigned column to true for the floating ip
- self.db.floating_ip_set_auto_assigned(context, floating_address)
-
- # get the first fixed address belonging to the instance
- fixed_ips = nw_info.fixed_ips()
- fixed_address = fixed_ips[0]['address']
-
- # associate the floating ip to fixed_ip
- self.associate_floating_ip(context,
- floating_address,
- fixed_address,
- affect_auto_assigned=True)
-
- # create a fresh set of network info that contains the floating ip
- nw_info = self.get_instance_nw_info(context, **kwargs)
-
- return nw_info
-
- def deallocate_for_instance(self, context, **kwargs):
- """Handles deallocating floating IP resources for an instance.
-
- calls super class deallocate_for_instance() as well.
-
- rpc.called by network_api
- """
- instance_id = kwargs.get('instance_id')
-
- # NOTE(francois.charlier): in some cases the instance might be
- # deleted before the IPs are released, so we need to get deleted
- # instances too
- instance = self.db.instance_get(
- context.elevated(read_deleted='yes'), instance_id)
-
- try:
- fixed_ips = self.db.fixed_ip_get_by_instance(context,
- instance['uuid'])
- except exception.FixedIpNotFoundForInstance:
- fixed_ips = []
- # add to kwargs so we can pass to super to save a db lookup there
- kwargs['fixed_ips'] = fixed_ips
- for fixed_ip in fixed_ips:
- fixed_id = fixed_ip['id']
- floating_ips = self.db.floating_ip_get_by_fixed_ip_id(context,
- fixed_id)
- # disassociate floating ips related to fixed_ip
- for floating_ip in floating_ips:
- address = floating_ip['address']
- try:
- self.disassociate_floating_ip(context,
- address,
- affect_auto_assigned=True)
- except exception.FloatingIpNotAssociated:
- LOG.exception(_("Floating IP is not associated. Ignore."))
- # deallocate if auto_assigned
- if floating_ip['auto_assigned']:
- self.deallocate_floating_ip(context, address,
- affect_auto_assigned=True)
-
- # call the next inherited class's deallocate_for_instance()
- # which is currently the NetworkManager version
- # call this after so floating IPs are handled first
- super(FloatingIP, self).deallocate_for_instance(context, **kwargs)
-
- def _floating_ip_owned_by_project(self, context, floating_ip):
- """Raises if floating ip does not belong to project."""
- if context.is_admin:
- return
-
- if floating_ip['project_id'] != context.project_id:
- if floating_ip['project_id'] is None:
- LOG.warn(_('Address |%(address)s| is not allocated'),
- {'address': floating_ip['address']})
- raise exception.NotAuthorized()
- else:
- LOG.warn(_('Address |%(address)s| is not allocated to your '
- 'project |%(project)s|'),
- {'address': floating_ip['address'],
- 'project': context.project_id})
- raise exception.NotAuthorized()
-
- def allocate_floating_ip(self, context, project_id, auto_assigned=False,
- pool=None):
- """Gets a floating ip from the pool."""
- # NOTE(tr3buchet): all network hosts in zone now use the same pool
- pool = pool or CONF.default_floating_pool
- use_quota = not auto_assigned
-
- # Check the quota; can't put this in the API because we get
- # called into from other places
- try:
- if use_quota:
- reservations = QUOTAS.reserve(context, floating_ips=1)
- except exception.OverQuota:
- pid = context.project_id
- LOG.warn(_("Quota exceeded for %(pid)s, tried to allocate "
- "floating IP") % locals())
- raise exception.FloatingIpLimitExceeded()
-
- try:
- floating_ip = self.db.floating_ip_allocate_address(context,
- project_id,
- pool)
- payload = dict(project_id=project_id, floating_ip=floating_ip)
- notifier.notify(context,
- notifier.publisher_id("network"),
- 'network.floating_ip.allocate',
- notifier.INFO, payload)
-
- # Commit the reservations
- if use_quota:
- QUOTAS.commit(context, reservations)
- except Exception:
- with excutils.save_and_reraise_exception():
- if use_quota:
- QUOTAS.rollback(context, reservations)
-
- return floating_ip
-
- @rpc_common.client_exceptions(exception.FloatingIpNotFoundForAddress)
- def deallocate_floating_ip(self, context, address,
- affect_auto_assigned=False):
- """Returns a floating ip to the pool."""
- floating_ip = self.db.floating_ip_get_by_address(context, address)
-
- # handle auto_assigned
- if not affect_auto_assigned and floating_ip.get('auto_assigned'):
- return
- use_quota = not floating_ip.get('auto_assigned')
-
- # make sure project owns this floating ip (allocated)
- self._floating_ip_owned_by_project(context, floating_ip)
-
- # make sure floating ip is not associated
- if floating_ip['fixed_ip_id']:
- floating_address = floating_ip['address']
- raise exception.FloatingIpAssociated(address=floating_address)
-
- # clean up any associated DNS entries
- self._delete_all_entries_for_ip(context,
- floating_ip['address'])
- payload = dict(project_id=floating_ip['project_id'],
- floating_ip=floating_ip['address'])
- notifier.notify(context,
- notifier.publisher_id("network"),
- 'network.floating_ip.deallocate',
- notifier.INFO, payload=payload)
-
- # Get reservations...
- try:
- if use_quota:
- reservations = QUOTAS.reserve(context, floating_ips=-1)
- else:
- reservations = None
- except Exception:
- reservations = None
- LOG.exception(_("Failed to update usages deallocating "
- "floating IP"))
-
- self.db.floating_ip_deallocate(context, address)
-
- # Commit the reservations
- if reservations:
- QUOTAS.commit(context, reservations)
-
- @rpc_common.client_exceptions(exception.FloatingIpNotFoundForAddress)
- def associate_floating_ip(self, context, floating_address, fixed_address,
- affect_auto_assigned=False):
- """Associates a floating ip with a fixed ip.
-
- Makes sure everything makes sense then calls _associate_floating_ip,
- rpc'ing to correct host if i'm not it.
- """
- floating_ip = self.db.floating_ip_get_by_address(context,
- floating_address)
- # handle auto_assigned
- if not affect_auto_assigned and floating_ip.get('auto_assigned'):
- return
-
- # make sure project owns this floating ip (allocated)
- self._floating_ip_owned_by_project(context, floating_ip)
-
- # disassociate any already associated
- orig_instance_uuid = None
- if floating_ip['fixed_ip_id']:
- # find previously associated instance
- fixed_ip = self.db.fixed_ip_get(context,
- floating_ip['fixed_ip_id'])
- if fixed_ip['address'] == fixed_address:
- # NOTE(vish): already associated to this address
- return
- orig_instance_uuid = fixed_ip['instance_uuid']
-
- self.disassociate_floating_ip(context, floating_address)
-
- fixed_ip = self.db.fixed_ip_get_by_address(context, fixed_address)
-
- # send to correct host, unless i'm the correct host
- network = self._get_network_by_id(context.elevated(),
- fixed_ip['network_id'])
- if network['multi_host']:
- instance = self.db.instance_get_by_uuid(context,
- fixed_ip['instance_uuid'])
- host = instance['host']
- else:
- host = network['host']
-
- interface = floating_ip.get('interface')
- if host == self.host:
- # i'm the correct host
- self._associate_floating_ip(context, floating_address,
- fixed_address, interface,
- fixed_ip['instance_uuid'])
- else:
- # send to correct host
- self.network_rpcapi._associate_floating_ip(context,
- floating_address, fixed_address, interface, host,
- fixed_ip['instance_uuid'])
-
- return orig_instance_uuid
-
- def _associate_floating_ip(self, context, floating_address, fixed_address,
- interface, instance_uuid):
- """Performs db and driver calls to associate floating ip & fixed ip."""
- interface = CONF.public_interface or interface
-
- @lockutils.synchronized(unicode(floating_address), 'nova-')
- def do_associate():
- # associate floating ip
- fixed = self.db.floating_ip_fixed_ip_associate(context,
- floating_address,
- fixed_address,
- self.host)
- if not fixed:
- # NOTE(vish): ip was already associated
- return
- try:
- # gogo driver time
- self.l3driver.add_floating_ip(floating_address, fixed_address,
- interface, fixed['network'])
- except exception.ProcessExecutionError as e:
- self.db.floating_ip_disassociate(context, floating_address)
- if "Cannot find device" in str(e):
- LOG.error(_('Interface %(interface)s not found'), locals())
- raise exception.NoFloatingIpInterface(interface=interface)
-
- payload = dict(project_id=context.project_id,
- instance_id=instance_uuid,
- floating_ip=floating_address)
- notifier.notify(context,
- notifier.publisher_id("network"),
- 'network.floating_ip.associate',
- notifier.INFO, payload=payload)
- do_associate()
-
- @rpc_common.client_exceptions(exception.FloatingIpNotFoundForAddress)
- def disassociate_floating_ip(self, context, address,
- affect_auto_assigned=False):
- """Disassociates a floating ip from its fixed ip.
-
- Makes sure everything makes sense then calls _disassociate_floating_ip,
- rpc'ing to correct host if i'm not it.
- """
- floating_ip = self.db.floating_ip_get_by_address(context, address)
-
- # handle auto assigned
- if not affect_auto_assigned and floating_ip.get('auto_assigned'):
- raise exception.CannotDisassociateAutoAssignedFloatingIP()
-
- # make sure project owns this floating ip (allocated)
- self._floating_ip_owned_by_project(context, floating_ip)
-
- # make sure floating ip is associated
- if not floating_ip.get('fixed_ip_id'):
- floating_address = floating_ip['address']
- raise exception.FloatingIpNotAssociated(address=floating_address)
-
- fixed_ip = self.db.fixed_ip_get(context, floating_ip['fixed_ip_id'])
-
- # send to correct host, unless i'm the correct host
- network = self._get_network_by_id(context, fixed_ip['network_id'])
- interface = floating_ip.get('interface')
- if network['multi_host']:
- instance = self.db.instance_get_by_uuid(context,
- fixed_ip['instance_uuid'])
- service = self.db.service_get_by_host_and_topic(
- context.elevated(), instance['host'], 'network')
- if service and self.servicegroup_api.service_is_up(service):
- host = instance['host']
- else:
- # NOTE(vish): if the service is down just deallocate the data
- # locally. Set the host to local so the call will
- # not go over rpc and set interface to None so the
- # teardown in the driver does not happen.
- host = self.host
- interface = None
- else:
- host = network['host']
-
- if host == self.host:
- # i'm the correct host
- self._disassociate_floating_ip(context, address, interface,
- fixed_ip['instance_uuid'])
- else:
- # send to correct host
- self.network_rpcapi._disassociate_floating_ip(context, address,
- interface, host, fixed_ip['instance_uuid'])
-
- def _disassociate_floating_ip(self, context, address, interface,
- instance_uuid):
- """Performs db and driver calls to disassociate floating ip."""
- interface = CONF.public_interface or interface
-
- @lockutils.synchronized(unicode(address), 'nova-')
- def do_disassociate():
- # NOTE(vish): Note that we are disassociating in the db before we
- # actually remove the ip address on the host. We are
- # safe from races on this host due to the decorator,
- # but another host might grab the ip right away. We
- # don't worry about this case because the minuscule
- # window where the ip is on both hosts shouldn't cause
- # any problems.
- fixed = self.db.floating_ip_disassociate(context, address)
-
- if not fixed:
- # NOTE(vish): ip was already disassociated
- return
- if interface:
- # go go driver time
- self.l3driver.remove_floating_ip(address, fixed['address'],
- interface, fixed['network'])
- payload = dict(project_id=context.project_id,
- instance_id=instance_uuid,
- floating_ip=address)
- notifier.notify(context,
- notifier.publisher_id("network"),
- 'network.floating_ip.disassociate',
- notifier.INFO, payload=payload)
- do_disassociate()
-
- @rpc_common.client_exceptions(exception.FloatingIpNotFound)
- def get_floating_ip(self, context, id):
- """Returns a floating IP as a dict."""
- # NOTE(vish): This is no longer used but can't be removed until
- # we major version the network_rpcapi.
- return dict(self.db.floating_ip_get(context, id).iteritems())
-
- def get_floating_pools(self, context):
- """Returns list of floating pools."""
- # NOTE(maurosr) This method should be removed in future, replaced by
- # get_floating_ip_pools. See bug #1091668
- return self.get_floating_ip_pools(context)
-
- def get_floating_ip_pools(self, context):
- """Returns list of floating ip pools."""
- # NOTE(vish): This is no longer used but can't be removed until
- # we major version the network_rpcapi.
- pools = self.db.floating_ip_get_pools(context)
- return [dict(pool.iteritems()) for pool in pools]
-
- def get_floating_ip_by_address(self, context, address):
- """Returns a floating IP as a dict."""
- # NOTE(vish): This is no longer used but can't be removed until
- # we major version the network_rpcapi.
- return dict(self.db.floating_ip_get_by_address(context,
- address).iteritems())
-
- def get_floating_ips_by_project(self, context):
- """Returns the floating IPs allocated to a project."""
- # NOTE(vish): This is no longer used but can't be removed until
- # we major version the network_rpcapi.
- ips = self.db.floating_ip_get_all_by_project(context,
- context.project_id)
- return [dict(ip.iteritems()) for ip in ips]
-
- def get_floating_ips_by_fixed_address(self, context, fixed_address):
- """Returns the floating IPs associated with a fixed_address."""
- # NOTE(vish): This is no longer used but can't be removed until
- # we major version the network_rpcapi.
- floating_ips = self.db.floating_ip_get_by_fixed_address(context,
- fixed_address)
- return [floating_ip['address'] for floating_ip in floating_ips]
-
- def _is_stale_floating_ip_address(self, context, floating_ip):
- try:
- self._floating_ip_owned_by_project(context, floating_ip)
- except exception.NotAuthorized:
- return True
- return False if floating_ip.get('fixed_ip_id') else True
-
- def migrate_instance_start(self, context, instance_uuid,
- floating_addresses,
- rxtx_factor=None, project_id=None,
- source=None, dest=None):
- # We only care if floating_addresses are provided and we're
- # switching hosts
- if not floating_addresses or (source and source == dest):
- return
-
- LOG.info(_("Starting migration network for instance"
- " %(instance_uuid)s"), locals())
- for address in floating_addresses:
- floating_ip = self.db.floating_ip_get_by_address(context,
- address)
-
- if self._is_stale_floating_ip_address(context, floating_ip):
- LOG.warn(_("Floating ip address |%(address)s| no longer "
- "belongs to instance %(instance_uuid)s. Will not"
- "migrate it "), locals())
- continue
-
- interface = CONF.public_interface or floating_ip['interface']
- fixed_ip = self.db.fixed_ip_get(context,
- floating_ip['fixed_ip_id'],
- get_network=True)
- self.l3driver.remove_floating_ip(floating_ip['address'],
- fixed_ip['address'],
- interface,
- fixed_ip['network'])
-
- # NOTE(wenjianhn): Make this address will not be bound to public
- # interface when restarts nova-network on dest compute node
- self.db.floating_ip_update(context,
- floating_ip['address'],
- {'host': None})
-
- def migrate_instance_finish(self, context, instance_uuid,
- floating_addresses, host=None,
- rxtx_factor=None, project_id=None,
- source=None, dest=None):
- # We only care if floating_addresses are provided and we're
- # switching hosts
- if host and not dest:
- dest = host
- if not floating_addresses or (source and source == dest):
- return
-
- LOG.info(_("Finishing migration network for instance"
- " %(instance_uuid)s"), locals())
-
- for address in floating_addresses:
- floating_ip = self.db.floating_ip_get_by_address(context,
- address)
-
- if self._is_stale_floating_ip_address(context, floating_ip):
- LOG.warn(_("Floating ip address |%(address)s| no longer "
- "belongs to instance %(instance_uuid)s. Will not"
- "setup it."), locals())
- continue
-
- self.db.floating_ip_update(context,
- floating_ip['address'],
- {'host': dest})
-
- interface = CONF.public_interface or floating_ip['interface']
- fixed_ip = self.db.fixed_ip_get(context,
- floating_ip['fixed_ip_id'],
- get_network=True)
- self.l3driver.add_floating_ip(floating_ip['address'],
- fixed_ip['address'],
- interface,
- fixed_ip['network'])
-
- def _prepare_domain_entry(self, context, domain):
- domainref = self.db.dnsdomain_get(context, domain)
- scope = domainref['scope']
- if scope == 'private':
- av_zone = domainref['availability_zone']
- this_domain = {'domain': domain,
- 'scope': scope,
- 'availability_zone': av_zone}
- else:
- project = domainref['project_id']
- this_domain = {'domain': domain,
- 'scope': scope,
- 'project': project}
- return this_domain
-
- def get_dns_domains(self, context):
- domains = []
-
- db_domain_list = self.db.dnsdomain_list(context)
- floating_driver_domain_list = self.floating_dns_manager.get_domains()
- instance_driver_domain_list = self.instance_dns_manager.get_domains()
-
- for db_domain in db_domain_list:
- if (db_domain in floating_driver_domain_list or
- db_domain in instance_driver_domain_list):
- domain_entry = self._prepare_domain_entry(context,
- db_domain)
- if domain_entry:
- domains.append(domain_entry)
- else:
- LOG.warn(_('Database inconsistency: DNS domain |%s| is '
- 'registered in the Nova db but not visible to '
- 'either the floating or instance DNS driver. It '
- 'will be ignored.'), db_domain)
-
- return domains
-
- def add_dns_entry(self, context, address, name, dns_type, domain):
- self.floating_dns_manager.create_entry(name, address,
- dns_type, domain)
-
- def modify_dns_entry(self, context, address, name, domain):
- self.floating_dns_manager.modify_address(name, address,
- domain)
-
- def delete_dns_entry(self, context, name, domain):
- self.floating_dns_manager.delete_entry(name, domain)
-
- def _delete_all_entries_for_ip(self, context, address):
- domain_list = self.get_dns_domains(context)
- for domain in domain_list:
- names = self.get_dns_entries_by_address(context,
- address,
- domain['domain'])
- for name in names:
- self.delete_dns_entry(context, name, domain['domain'])
-
- def get_dns_entries_by_address(self, context, address, domain):
- return self.floating_dns_manager.get_entries_by_address(address,
- domain)
-
- def get_dns_entries_by_name(self, context, name, domain):
- return self.floating_dns_manager.get_entries_by_name(name,
- domain)
-
- def create_private_dns_domain(self, context, domain, av_zone):
- self.db.dnsdomain_register_for_zone(context, domain, av_zone)
- try:
- self.instance_dns_manager.create_domain(domain)
- except exception.FloatingIpDNSExists:
- LOG.warn(_('Domain |%(domain)s| already exists, '
- 'changing zone to |%(av_zone)s|.'),
- {'domain': domain, 'av_zone': av_zone})
-
- def create_public_dns_domain(self, context, domain, project):
- self.db.dnsdomain_register_for_project(context, domain, project)
- try:
- self.floating_dns_manager.create_domain(domain)
- except exception.FloatingIpDNSExists:
- LOG.warn(_('Domain |%(domain)s| already exists, '
- 'changing project to |%(project)s|.'),
- {'domain': domain, 'project': project})
-
- def delete_dns_domain(self, context, domain):
- self.db.dnsdomain_unregister(context, domain)
- self.floating_dns_manager.delete_domain(domain)
-
- def _get_project_for_domain(self, context, domain):
- return self.db.dnsdomain_project(context, domain)
-
-
class NetworkManager(manager.SchedulerDependentManager):
"""Implements common network manager functionality.
@@ -2088,7 +1463,8 @@ class FlatManager(NetworkManager):
pass
-class FlatDHCPManager(RPCAllocateFixedIP, FloatingIP, NetworkManager):
+class FlatDHCPManager(RPCAllocateFixedIP, floating_ips.FloatingIP,
+ NetworkManager):
"""Flat networking with dhcp.
FlatDHCPManager will start up one dhcp server to give out addresses.
@@ -2151,7 +1527,7 @@ class FlatDHCPManager(RPCAllocateFixedIP, FloatingIP, NetworkManager):
return network_dict
-class VlanManager(RPCAllocateFixedIP, FloatingIP, NetworkManager):
+class VlanManager(RPCAllocateFixedIP, floating_ips.FloatingIP, NetworkManager):
"""Vlan network with dhcp.
VlanManager is the most complicated. It will create a host-managed
diff --git a/nova/network/quantumv2/api.py b/nova/network/quantumv2/api.py
index 1c8c60113..4a4a74392 100644
--- a/nova/network/quantumv2/api.py
+++ b/nova/network/quantumv2/api.py
@@ -59,7 +59,7 @@ quantum_opts = [
CONF = cfg.CONF
CONF.register_opts(quantum_opts)
-CONF.import_opt('default_floating_pool', 'nova.network.manager')
+CONF.import_opt('default_floating_pool', 'nova.network.floating_ips')
LOG = logging.getLogger(__name__)
NET_EXTERNAL = 'router:external'
diff --git a/nova/tests/network/test_manager.py b/nova/tests/network/test_manager.py
index 2cc19bbb8..48183010f 100644
--- a/nova/tests/network/test_manager.py
+++ b/nova/tests/network/test_manager.py
@@ -24,6 +24,7 @@ from nova import db
from nova.db.sqlalchemy import models
from nova import exception
from nova import ipv6
+from nova.network import floating_ips
from nova.network import linux_net
from nova.network import manager as network_manager
from nova.network import model as net_model
@@ -1577,7 +1578,7 @@ class BackdoorPortTestCase(test.TestCase):
self.assertEqual(port, self.manager.backdoor_port)
-class TestFloatingIPManager(network_manager.FloatingIP,
+class TestFloatingIPManager(floating_ips.FloatingIP,
network_manager.NetworkManager):
"""Dummy manager that implements FloatingIP."""
@@ -1667,8 +1668,8 @@ class FloatingIPTestCase(test.TestCase):
'fixed_ip_get',
lambda _x, _y: fixed_ip)
- self.stubs.Set(self.network,
- '_get_network_by_id',
+ self.stubs.Set(self.network.db,
+ 'network_get',
lambda _x, _y: network)
self.stubs.Set(self.network.db,
@@ -1725,8 +1726,8 @@ class FloatingIPTestCase(test.TestCase):
'fixed_ip_get_by_address',
lambda _x, _y: fixed_ip)
- self.stubs.Set(self.network,
- '_get_network_by_id',
+ self.stubs.Set(self.network.db,
+ 'network_get',
lambda _x, _y: network)
self.stubs.Set(self.network.db,