diff options
-rw-r--r-- | nova/conductor/api.py | 24 | ||||
-rw-r--r-- | nova/network/api.py | 39 | ||||
-rw-r--r-- | nova/network/floating_ips.py | 27 | ||||
-rw-r--r-- | nova/network/manager.py | 9 | ||||
-rw-r--r-- | nova/tests/api/openstack/compute/contrib/test_floating_ips.py | 13 | ||||
-rw-r--r-- | nova/tests/conf_fixture.py | 4 | ||||
-rw-r--r-- | nova/tests/network/test_api.py | 7 | ||||
-rw-r--r-- | nova/utils.py | 20 |
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 |