summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--nova/conductor/api.py24
-rw-r--r--nova/network/api.py39
-rw-r--r--nova/network/floating_ips.py27
-rw-r--r--nova/network/manager.py9
-rw-r--r--nova/tests/api/openstack/compute/contrib/test_floating_ips.py13
-rw-r--r--nova/tests/conf_fixture.py4
-rw-r--r--nova/tests/network/test_api.py7
-rw-r--r--nova/utils.py20
8 files changed, 87 insertions, 56 deletions
diff --git a/nova/conductor/api.py b/nova/conductor/api.py
index 7250bbfe4..a30f8dffa 100644
--- a/nova/conductor/api.py
+++ b/nova/conductor/api.py
@@ -14,14 +14,13 @@
"""Handles all requests to the conductor service."""
-import functools
-
from nova.conductor import manager
from nova.conductor import rpcapi
from nova import exception as exc
from nova.openstack.common import cfg
from nova.openstack.common import log as logging
from nova.openstack.common.rpc import common as rpc_common
+from nova import utils
conductor_opts = [
cfg.BoolOpt('use_local',
@@ -43,25 +42,6 @@ CONF.register_opts(conductor_opts, conductor_group)
LOG = logging.getLogger(__name__)
-class ExceptionHelper(object):
- """Class to wrap another and translate the ClientExceptions raised by its
- function calls to the actual ones"""
-
- def __init__(self, target):
- self._target = target
-
- def __getattr__(self, name):
- func = getattr(self._target, name)
-
- @functools.wraps(func)
- def wrapper(*args, **kwargs):
- try:
- return func(*args, **kwargs)
- except rpc_common.ClientException, e:
- raise (e._exc_info[1], None, e._exc_info[2])
- return wrapper
-
-
class LocalAPI(object):
"""A local version of the conductor API that does database updates
locally instead of via RPC"""
@@ -69,7 +49,7 @@ class LocalAPI(object):
def __init__(self):
# TODO(danms): This needs to be something more generic for
# other/future users of this sort of functionality.
- self._manager = ExceptionHelper(manager.ConductorManager())
+ self._manager = utils.ExceptionHelper(manager.ConductorManager())
def wait_until_ready(self, context, *args, **kwargs):
# nothing to wait for in the local case.
diff --git a/nova/network/api.py b/nova/network/api.py
index 0e19badc2..8a173ba45 100644
--- a/nova/network/api.py
+++ b/nova/network/api.py
@@ -22,10 +22,12 @@ import inspect
from nova.db import base
from nova import exception
+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 log as logging
from nova import policy
+from nova import utils
LOG = logging.getLogger(__name__)
@@ -103,11 +105,14 @@ class API(base.Base):
This is a pluggable module - other implementations do networking via
other services (such as Quantum).
"""
-
_sentinel = object()
def __init__(self, **kwargs):
self.network_rpcapi = network_rpcapi.NetworkAPI()
+ helper = utils.ExceptionHelper
+ # NOTE(vish): this local version of floating_manager has to convert
+ # ClientExceptions back since they aren't going over rpc.
+ self.floating_manager = helper(floating_ips.LocalManager())
super(API, self).__init__(**kwargs)
@wrap_check_policy
@@ -190,19 +195,15 @@ class API(base.Base):
@wrap_check_policy
def allocate_floating_ip(self, context, pool=None):
"""Adds (allocates) a floating ip to a project from a pool."""
- # NOTE(vish): We don't know which network host should get the ip
- # when we allocate, so just send it to any one. This
- # will probably need to move into a network supervisor
- # at some point.
- return self.network_rpcapi.allocate_floating_ip(context,
- context.project_id, pool, False)
+ return self.floating_manager.allocate_floating_ip(context,
+ context.project_id, False, pool)
@wrap_check_policy
def release_floating_ip(self, context, address,
affect_auto_assigned=False):
"""Removes (deallocates) a floating ip with address from a project."""
- return self.network_rpcapi.deallocate_floating_ip(context, address,
- affect_auto_assigned)
+ return self.floating_manager.deallocate_floating_ip(context, address,
+ affect_auto_assigned)
@wrap_check_policy
@refresh_cache
@@ -211,10 +212,13 @@ class API(base.Base):
affect_auto_assigned=False):
"""Associates a floating ip with a fixed ip.
- ensures floating ip is allocated to the project in context
+ Ensures floating ip is allocated to the project in context.
+ Does not verify ownership of the fixed ip. Caller is assumed to have
+ checked that the instance is properly owned.
+
"""
- orig_instance_uuid = self.network_rpcapi.associate_floating_ip(context,
- floating_address, fixed_address, affect_auto_assigned)
+ orig_instance_uuid = self.floating_manager.associate_floating_ip(
+ context, floating_address, fixed_address, affect_auto_assigned)
if orig_instance_uuid:
msg_dict = dict(address=floating_address,
@@ -232,7 +236,7 @@ class API(base.Base):
def disassociate_floating_ip(self, context, instance, address,
affect_auto_assigned=False):
"""Disassociates a floating ip from fixed ip it is associated with."""
- self.network_rpcapi.disassociate_floating_ip(context, address,
+ return self.floating_manager.disassociate_floating_ip(context, address,
affect_auto_assigned)
@wrap_check_policy
@@ -249,6 +253,10 @@ class API(base.Base):
with requested_networks which is user supplied).
:returns: network info as from get_instance_nw_info() below
"""
+ # NOTE(vish): We can't do the floating ip allocation here because
+ # this is called from compute.manager which shouldn't
+ # have db access so we do it on the other side of the
+ # rpc.
args = {}
args['vpn'] = vpn
args['requested_networks'] = requested_networks
@@ -265,7 +273,10 @@ class API(base.Base):
@wrap_check_policy
def deallocate_for_instance(self, context, instance):
"""Deallocates all network structures related to instance."""
-
+ # NOTE(vish): We can't do the floating ip deallocation here because
+ # this is called from compute.manager which shouldn't
+ # have db access so we do it on the other side of the
+ # rpc.
args = {}
args['instance_id'] = instance['id']
args['project_id'] = instance['project_id']
diff --git a/nova/network/floating_ips.py b/nova/network/floating_ips.py
index ce49f69e3..4b0a66492 100644
--- a/nova/network/floating_ips.py
+++ b/nova/network/floating_ips.py
@@ -18,14 +18,18 @@
# under the License.
from nova import context
+from nova.db import base
from nova import exception
+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 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
+from nova import servicegroup
LOG = logging.getLogger(__name__)
@@ -38,6 +42,15 @@ floating_opts = [
cfg.BoolOpt('auto_assign_floating_ip',
default=False,
help='Autoassigning floating ip to VM'),
+ cfg.StrOpt('floating_ip_dns_manager',
+ default='nova.network.noop_dns_driver.NoopDNSDriver',
+ help='full class name for the DNS Manager for floating IPs'),
+ cfg.StrOpt('instance_dns_manager',
+ default='nova.network.noop_dns_driver.NoopDNSDriver',
+ help='full class name for the DNS Manager for instance IPs'),
+ cfg.StrOpt('instance_dns_domain',
+ default='',
+ help='full class name for the DNS Zone for instance IPs'),
]
CONF = cfg.CONF
@@ -662,3 +675,17 @@ class FloatingIP(object):
def _get_project_for_domain(self, context, domain):
return self.db.dnsdomain_project(context, domain)
+
+
+class LocalManager(base.Base, FloatingIP):
+ def __init__(self):
+ super(LocalManager, self).__init__()
+ # NOTE(vish): setting the host to none ensures that the actual
+ # l3driver commands for l3 are done via rpc.
+ self.host = None
+ self.servicegroup_api = servicegroup.API()
+ self.network_rpcapi = network_rpcapi.NetworkAPI()
+ self.floating_dns_manager = importutils.import_object(
+ CONF.floating_ip_dns_manager)
+ self.instance_dns_manager = importutils.import_object(
+ CONF.instance_dns_manager)
diff --git a/nova/network/manager.py b/nova/network/manager.py
index a0bd3c807..f893768e7 100644
--- a/nova/network/manager.py
+++ b/nova/network/manager.py
@@ -164,15 +164,6 @@ network_opts = [
cfg.StrOpt('l3_lib',
default='nova.network.l3.LinuxNetL3',
help="Indicates underlying L3 management library"),
- cfg.StrOpt('instance_dns_manager',
- default='nova.network.noop_dns_driver.NoopDNSDriver',
- help='full class name for the DNS Manager for instance IPs'),
- cfg.StrOpt('instance_dns_domain',
- default='',
- help='full class name for the DNS Zone for instance IPs'),
- cfg.StrOpt('floating_ip_dns_manager',
- default='nova.network.noop_dns_driver.NoopDNSDriver',
- help='full class name for the DNS Manager for floating IPs'),
]
CONF = cfg.CONF
diff --git a/nova/tests/api/openstack/compute/contrib/test_floating_ips.py b/nova/tests/api/openstack/compute/contrib/test_floating_ips.py
index b6b8dd630..864ab7a9f 100644
--- a/nova/tests/api/openstack/compute/contrib/test_floating_ips.py
+++ b/nova/tests/api/openstack/compute/contrib/test_floating_ips.py
@@ -27,7 +27,6 @@ from nova import db
from nova import exception
from nova import network
from nova.openstack.common import jsonutils
-from nova.openstack.common import rpc
from nova import test
from nova.tests.api.openstack import fakes
from nova.tests import fake_network
@@ -275,12 +274,11 @@ class FloatingIpTest(test.TestCase):
self.assertIn(self.floating_ip, ip_list)
self.assertNotIn(self.floating_ip_2, ip_list)
-# test floating ip allocate/release(deallocate)
def test_floating_ip_allocate_no_free_ips(self):
- def fake_call(*args, **kwargs):
+ def fake_allocate(*args, **kwargs):
raise exception.NoMoreFloatingIps()
- self.stubs.Set(rpc, "call", fake_call)
+ self.stubs.Set(network.api.API, "allocate_floating_ip", fake_allocate)
req = fakes.HTTPRequest.blank('/v2/fake/os-floating-ips')
self.assertRaises(exception.NoMoreFloatingIps,
@@ -316,9 +314,12 @@ class FloatingIpTest(test.TestCase):
req = fakes.HTTPRequest.blank('/v2/fake/os-floating-ips/1')
self.controller.delete(req, 1)
-# test floating ip add/remove -> associate/disassociate
-
def test_floating_ip_associate(self):
+ def fake_associate_floating_ip(*args, **kwargs):
+ pass
+
+ self.stubs.Set(network.api.API, "associate_floating_ip",
+ fake_associate_floating_ip)
body = dict(addFloatingIp=dict(address=self.floating_ip))
req = fakes.HTTPRequest.blank('/v2/fake/servers/test_inst/action')
diff --git a/nova/tests/conf_fixture.py b/nova/tests/conf_fixture.py
index 2f4d0ebb1..230f70a1b 100644
--- a/nova/tests/conf_fixture.py
+++ b/nova/tests/conf_fixture.py
@@ -30,8 +30,8 @@ CONF.import_opt('scheduler_driver', 'nova.scheduler.manager')
CONF.import_opt('fake_network', 'nova.network.manager')
CONF.import_opt('network_size', 'nova.network.manager')
CONF.import_opt('num_networks', 'nova.network.manager')
-CONF.import_opt('floating_ip_dns_manager', 'nova.network.manager')
-CONF.import_opt('instance_dns_manager', 'nova.network.manager')
+CONF.import_opt('floating_ip_dns_manager', 'nova.network.floating_ips')
+CONF.import_opt('instance_dns_manager', 'nova.network.floating_ips')
CONF.import_opt('policy_file', 'nova.policy')
CONF.import_opt('compute_driver', 'nova.virt.driver')
CONF.import_opt('api_paste_config', 'nova.wsgi')
diff --git a/nova/tests/network/test_api.py b/nova/tests/network/test_api.py
index 8e9abe1db..01c727c17 100644
--- a/nova/tests/network/test_api.py
+++ b/nova/tests/network/test_api.py
@@ -26,8 +26,8 @@ from nova import context
from nova import exception
from nova import network
from nova.network import api
+from nova.network import floating_ips
from nova.network import rpcapi as network_rpcapi
-from nova.openstack.common import rpc
from nova import policy
from nova import test
@@ -90,10 +90,11 @@ class ApiTestCase(test.TestCase):
new_instance = {'uuid': 'new-uuid'}
- def fake_rpc_call(context, topic, msg, timeout=None):
+ def fake_associate(*args, **kwargs):
return orig_instance_uuid
- self.stubs.Set(rpc, 'call', fake_rpc_call)
+ self.stubs.Set(floating_ips.FloatingIP, 'associate_floating_ip',
+ fake_associate)
def fake_instance_get_by_uuid(context, instance_uuid):
return {'uuid': instance_uuid}
diff --git a/nova/utils.py b/nova/utils.py
index 545cb5dae..7ad810504 100644
--- a/nova/utils.py
+++ b/nova/utils.py
@@ -48,6 +48,7 @@ from nova.openstack.common import cfg
from nova.openstack.common import excutils
from nova.openstack.common import importutils
from nova.openstack.common import log as logging
+from nova.openstack.common.rpc import common as rpc_common
from nova.openstack.common import timeutils
notify_decorator = 'nova.openstack.common.notifier.api.notify_decorator'
@@ -1321,3 +1322,22 @@ def getcallargs(function, *args, **kwargs):
keyed_args[argname] = value
return keyed_args
+
+
+class ExceptionHelper(object):
+ """Class to wrap another and translate the ClientExceptions raised by its
+ function calls to the actual ones"""
+
+ def __init__(self, target):
+ self._target = target
+
+ def __getattr__(self, name):
+ func = getattr(self._target, name)
+
+ @functools.wraps(func)
+ def wrapper(*args, **kwargs):
+ try:
+ return func(*args, **kwargs)
+ except rpc_common.ClientException, e:
+ raise (e._exc_info[1], None, e._exc_info[2])
+ return wrapper