summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJenkins <jenkins@review.openstack.org>2012-10-18 06:07:11 +0000
committerGerrit Code Review <review@openstack.org>2012-10-18 06:07:11 +0000
commit5d677e204c99fbcf86e0c721ad2fd327a03c35c2 (patch)
tree904f99038bf806c9b96465ba2dead77dee929f4f
parent5c94eea7edae746c017372bc726977c2206bccd6 (diff)
parente8560a76cbaaebd25f60886f5966297a94597993 (diff)
Merge "Add version to network rpc API."
-rwxr-xr-xbin/nova-dhcpbridge14
-rw-r--r--nova/network/api.py208
-rw-r--r--nova/network/manager.py53
-rw-r--r--nova/network/rpcapi.py274
-rw-r--r--nova/tests/compute/test_compute.py6
-rw-r--r--nova/tests/network/test_api.py2
-rw-r--r--nova/tests/network/test_rpcapi.py260
7 files changed, 622 insertions, 195 deletions
diff --git a/bin/nova-dhcpbridge b/bin/nova-dhcpbridge
index 0693ae27a..114dee268 100755
--- a/bin/nova-dhcpbridge
+++ b/bin/nova-dhcpbridge
@@ -39,6 +39,7 @@ from nova import context
from nova import db
from nova import flags
from nova.network import linux_net
+from nova.network import rpcapi as network_rpcapi
from nova.openstack.common import importutils
from nova.openstack.common import log as logging
from nova.openstack.common import rpc
@@ -57,10 +58,8 @@ def add_lease(mac, ip_address):
network_manager.lease_fixed_ip(context.get_admin_context(),
ip_address)
else:
- rpc.cast(context.get_admin_context(),
- "%s.%s" % (FLAGS.network_topic, FLAGS.host),
- {"method": "lease_fixed_ip",
- "args": {"address": ip_address}})
+ api = network_rpcapi.NetworkAPI()
+ api.lease_fixed_ip(context.get_admin_context(), ip_address, FLAGS.host)
def old_lease(mac, ip_address):
@@ -79,10 +78,9 @@ def del_lease(mac, ip_address):
network_manager.release_fixed_ip(context.get_admin_context(),
ip_address)
else:
- rpc.cast(context.get_admin_context(),
- "%s.%s" % (FLAGS.network_topic, FLAGS.host),
- {"method": "release_fixed_ip",
- "args": {"address": ip_address}})
+ api = network_rpcapi.NetworkAPI()
+ api.release_fixed_ip(context.get_admin_context(), ip_address,
+ FLAGS.host)
def init_leases(network_id):
diff --git a/nova/network/api.py b/nova/network/api.py
index f98678ab0..6e5d8f22d 100644
--- a/nova/network/api.py
+++ b/nova/network/api.py
@@ -23,6 +23,7 @@ import inspect
from nova.db import base
from nova import flags
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.openstack.common import rpc
@@ -83,96 +84,58 @@ def update_instance_cache_with_nw_info(api, context, instance,
class API(base.Base):
"""API for interacting with the network manager."""
+ def __init__(self, **kwargs):
+ self.network_rpcapi = network_rpcapi.NetworkAPI()
+ super(API, self).__init__(**kwargs)
+
def get_all(self, context):
- return rpc.call(context,
- FLAGS.network_topic,
- {'method': 'get_all_networks'})
+ return self.network_rpcapi.get_all_networks(context)
def get(self, context, network_uuid):
- return rpc.call(context,
- FLAGS.network_topic,
- {'method': 'get_network',
- 'args': {'network_uuid': network_uuid}})
+ return self.network_rpcapi.get_network(context, network_uuid)
def create(self, context, **kwargs):
- return rpc.call(context,
- FLAGS.network_topic,
- {'method': 'create_networks',
- 'args': kwargs})
+ return self.network_rpcapi.create_networks(context, **kwargs)
def delete(self, context, network_uuid):
- return rpc.call(context,
- FLAGS.network_topic,
- {'method': 'delete_network',
- 'args': {'fixed_range': None,
- 'uuid': network_uuid}})
+ return self.network_rpcapi.delete_network(context, network_uuid, None)
def disassociate(self, context, network_uuid):
- return rpc.call(context,
- FLAGS.network_topic,
- {'method': 'disassociate_network',
- 'args': {'network_uuid': network_uuid}})
+ return self.network_rpcapi.disassociate_network(context, network_uuid)
def get_fixed_ip(self, context, id):
- return rpc.call(context,
- FLAGS.network_topic,
- {'method': 'get_fixed_ip',
- 'args': {'id': id}})
+ return self.network_rpcapi.get_fixed_ip(context, id)
def get_fixed_ip_by_address(self, context, address):
- return rpc.call(context,
- FLAGS.network_topic,
- {'method': 'get_fixed_ip_by_address',
- 'args': {'address': address}})
+ return self.network_rpcapi.get_fixed_ip_by_address(context, address)
def get_floating_ip(self, context, id):
- return rpc.call(context,
- FLAGS.network_topic,
- {'method': 'get_floating_ip',
- 'args': {'id': id}})
+ return self.network_rpcapi.get_floating_ip(context, id)
def get_floating_ip_pools(self, context):
- return rpc.call(context,
- FLAGS.network_topic,
- {'method': 'get_floating_pools'})
+ return self.network_rpcapi.get_floating_pools(context)
def get_floating_ip_by_address(self, context, address):
- return rpc.call(context,
- FLAGS.network_topic,
- {'method': 'get_floating_ip_by_address',
- 'args': {'address': address}})
+ return self.network_rpcapi.get_floating_ip_by_address(context, address)
def get_floating_ips_by_project(self, context):
- return rpc.call(context,
- FLAGS.network_topic,
- {'method': 'get_floating_ips_by_project'})
+ return self.network_rpcapi.get_floating_ips_by_project(context)
def get_floating_ips_by_fixed_address(self, context, fixed_address):
- return rpc.call(context,
- FLAGS.network_topic,
- {'method': 'get_floating_ips_by_fixed_address',
- 'args': {'fixed_address': fixed_address}})
+ return self.network_rpcapi.get_floating_ips_by_fixed_address(context,
+ fixed_address)
def get_instance_id_by_floating_address(self, context, address):
# NOTE(tr3buchet): i hate this
- return rpc.call(context,
- FLAGS.network_topic,
- {'method': 'get_instance_id_by_floating_address',
- 'args': {'address': address}})
+ return self.network_rpcapi.get_instance_id_by_floating_address(context,
+ address)
def get_vifs_by_instance(self, context, instance):
- # NOTE(vish): When the db calls are converted to store network
- # data by instance_uuid, this should pass uuid instead.
- return rpc.call(context,
- FLAGS.network_topic,
- {'method': 'get_vifs_by_instance',
- 'args': {'instance_id': instance['id']}})
+ return self.network_rpcapi.get_vifs_by_instance(context,
+ instance['id'])
def get_vif_by_mac_address(self, context, mac_address):
- return rpc.call(context,
- FLAGS.network_topic,
- {'method': 'get_vif_by_mac_address',
- 'args': {'mac_address': mac_address}})
+ return self.network_rpcapi.get_vif_by_mac_address(context, mac_address)
def allocate_floating_ip(self, context, pool=None):
"""Adds a floating ip to a project from a pool. (allocates)"""
@@ -180,21 +143,14 @@ class API(base.Base):
# when we allocate, so just send it to any one. This
# will probably need to move into a network supervisor
# at some point.
- return rpc.call(context,
- FLAGS.network_topic,
- {'method': 'allocate_floating_ip',
- 'args': {'project_id': context.project_id,
- 'pool': pool,
- 'auto_assigned': False}})
+ return self.network_rpcapi.allocate_floating_ip(context,
+ context.project_id, pool, False)
def release_floating_ip(self, context, address,
affect_auto_assigned=False):
"""Removes floating ip with address from a project. (deallocates)"""
- rpc.call(context,
- FLAGS.network_topic,
- {'method': 'deallocate_floating_ip',
- 'args': {'address': address,
- 'affect_auto_assigned': affect_auto_assigned}})
+ return self.network_rpcapi.deallocate_floating_ip(context, address,
+ affect_auto_assigned)
@refresh_cache
def associate_floating_ip(self, context, instance,
@@ -204,12 +160,8 @@ class API(base.Base):
ensures floating ip is allocated to the project in context
"""
- orig_instance_uuid = rpc.call(context,
- FLAGS.network_topic,
- {'method': 'associate_floating_ip',
- 'args': {'floating_address': floating_address,
- 'fixed_address': fixed_address,
- 'affect_auto_assigned': affect_auto_assigned}})
+ orig_instance_uuid = self.network_rpcapi.associate_floating_ip(context,
+ floating_address, fixed_address, affect_auto_assigned)
if orig_instance_uuid:
msg_dict = dict(address=floating_address,
@@ -226,48 +178,43 @@ 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."""
- rpc.call(context,
- FLAGS.network_topic,
- {'method': 'disassociate_floating_ip',
- 'args': {'address': address}})
+ self.network_rpcapi.disassociate_floating_ip(context, address,
+ affect_auto_assigned)
@refresh_cache
- def allocate_for_instance(self, context, instance, **kwargs):
+ def allocate_for_instance(self, context, instance, vpn,
+ requested_networks):
"""Allocates all network structures for an instance.
:returns: network info as from get_instance_nw_info() below
"""
- args = kwargs
+ args = {}
+ args['vpn'] = vpn
+ args['requested_networks'] = requested_networks
args['instance_id'] = instance['id']
args['instance_uuid'] = instance['uuid']
args['project_id'] = instance['project_id']
args['host'] = instance['host']
args['rxtx_factor'] = instance['instance_type']['rxtx_factor']
-
- nw_info = rpc.call(context, FLAGS.network_topic,
- {'method': 'allocate_for_instance',
- 'args': args})
+ nw_info = self.network_rpcapi.allocate_for_instance(context, **args)
return network_model.NetworkInfo.hydrate(nw_info)
- def deallocate_for_instance(self, context, instance, **kwargs):
+ def deallocate_for_instance(self, context, instance):
"""Deallocates all network structures related to instance."""
- args = kwargs
+
+ args = {}
args['instance_id'] = instance['id']
args['project_id'] = instance['project_id']
args['host'] = instance['host']
- rpc.call(context, FLAGS.network_topic,
- {'method': 'deallocate_for_instance',
- 'args': args})
+ self.network_rpcapi.deallocate_for_instance(context, **args)
def add_fixed_ip_to_instance(self, context, instance, network_id):
"""Adds a fixed ip to instance from specified network."""
args = {'instance_id': instance['id'],
'host': instance['host'],
'network_id': network_id}
- rpc.call(context, FLAGS.network_topic,
- {'method': 'add_fixed_ip_to_instance',
- 'args': args})
+ self.network_rpcapi.add_fixed_ip_to_instance(context, **args)
def remove_fixed_ip_from_instance(self, context, instance, address):
"""Removes a fixed ip from instance from specified network."""
@@ -275,16 +222,12 @@ class API(base.Base):
args = {'instance_id': instance['uuid'],
'host': instance['host'],
'address': address}
- rpc.call(context, FLAGS.network_topic,
- {'method': 'remove_fixed_ip_from_instance',
- 'args': args})
+ self.network_rpcapi.remove_fixed_ip_from_instance(context, **args)
def add_network_to_project(self, context, project_id, network_uuid=None):
"""Force adds another network to a project."""
- rpc.call(context, FLAGS.network_topic,
- {'method': 'add_network_to_project',
- 'args': {'project_id': project_id,
- 'network_uuid': network_uuid}})
+ self.network_rpcapi.add_network_to_project(context, project_id,
+ network_uuid)
@refresh_cache
def get_instance_nw_info(self, context, instance):
@@ -298,9 +241,7 @@ class API(base.Base):
'rxtx_factor': instance['instance_type']['rxtx_factor'],
'host': instance['host'],
'project_id': instance['project_id']}
- nw_info = rpc.call(context, FLAGS.network_topic,
- {'method': 'get_instance_nw_info',
- 'args': args})
+ nw_info = self.network_rpcapi.get_instance_nw_info(context, **args)
return network_model.NetworkInfo.hydrate(nw_info)
@@ -308,27 +249,21 @@ class API(base.Base):
"""validate the networks passed at the time of creating
the server
"""
- args = {'networks': requested_networks}
- return rpc.call(context, FLAGS.network_topic,
- {'method': 'validate_networks',
- 'args': args})
+ return self.network_rpcapi.validate_networks(context,
+ requested_networks)
def get_instance_uuids_by_ip_filter(self, context, filters):
"""Returns a list of dicts in the form of
{'instance_uuid': uuid, 'ip': ip} that matched the ip_filter
"""
- args = {'filters': filters}
- return rpc.call(context, FLAGS.network_topic,
- {'method': 'get_instance_uuids_by_ip_filter',
- 'args': args})
+ return self.network_rpcapi.get_instance_uuids_by_ip_filter(context,
+ filters)
def get_dns_domains(self, context):
"""Returns a list of available dns domains.
These can be used to create DNS entries for floating ips.
"""
- return rpc.call(context,
- FLAGS.network_topic,
- {'method': 'get_dns_domains'})
+ return self.network_rpcapi.get_dns_domains(context)
def add_dns_entry(self, context, address, name, dns_type, domain):
"""Create specified DNS entry for address"""
@@ -336,60 +271,43 @@ class API(base.Base):
'name': name,
'dns_type': dns_type,
'domain': domain}
- return rpc.call(context, FLAGS.network_topic,
- {'method': 'add_dns_entry',
- 'args': args})
+ return self.network_rpcapi.add_dns_entry(context, **args)
def modify_dns_entry(self, context, name, address, domain):
"""Create specified DNS entry for address"""
args = {'address': address,
'name': name,
'domain': domain}
- return rpc.call(context, FLAGS.network_topic,
- {'method': 'modify_dns_entry',
- 'args': args})
+ return self.network_rpcapi.modify_dns_entry(context, **args)
def delete_dns_entry(self, context, name, domain):
"""Delete the specified dns entry."""
args = {'name': name, 'domain': domain}
- return rpc.call(context, FLAGS.network_topic,
- {'method': 'delete_dns_entry',
- 'args': args})
+ return self.network_rpcapi.delete_dns_entry(context, **args)
def delete_dns_domain(self, context, domain):
"""Delete the specified dns domain."""
- args = {'domain': domain}
- return rpc.call(context, FLAGS.network_topic,
- {'method': 'delete_dns_domain',
- 'args': args})
+ return self.network_rpcapi.delete_dns_domain(context, domain=domain)
def get_dns_entries_by_address(self, context, address, domain):
"""Get entries for address and domain"""
args = {'address': address, 'domain': domain}
- return rpc.call(context, FLAGS.network_topic,
- {'method': 'get_dns_entries_by_address',
- 'args': args})
+ return self.network_rpcapi.get_dns_entries_by_address(context, **args)
def get_dns_entries_by_name(self, context, name, domain):
"""Get entries for name and domain"""
args = {'name': name, 'domain': domain}
- return rpc.call(context, FLAGS.network_topic,
- {'method': 'get_dns_entries_by_name',
- 'args': args})
+ return self.network_rpcapi.get_dns_entries_by_name(context, **args)
def create_private_dns_domain(self, context, domain, availability_zone):
"""Create a private DNS domain with nova availability zone."""
args = {'domain': domain, 'av_zone': availability_zone}
- return rpc.call(context, FLAGS.network_topic,
- {'method': 'create_private_dns_domain',
- 'args': args})
+ return self.network_rpcapi.create_private_dns_domain(context, **args)
def create_public_dns_domain(self, context, domain, project=None):
- """Create a private DNS domain with optional nova project."""
+ """Create a public DNS domain with optional nova project."""
args = {'domain': domain, 'project': project}
- return rpc.call(context, FLAGS.network_topic,
- {'method': 'create_public_dns_domain',
- 'args': args})
+ return self.network_rpcapi.create_public_dns_domain(context, **args)
def setup_networks_on_host(self, context, instance, host=None,
teardown=False):
@@ -402,8 +320,4 @@ class API(base.Base):
args = {'instance_id': instance['id'],
'host': host,
'teardown': teardown}
-
- # NOTE(tr3buchet): the call is just to wait for completion
- rpc.call(context, FLAGS.network_topic,
- {'method': 'setup_networks_on_host',
- 'args': args})
+ self.network_rpcapi.setup_networks_on_host(context, **args)
diff --git a/nova/network/manager.py b/nova/network/manager.py
index 02cdfdd3a..f8ef65d3a 100644
--- a/nova/network/manager.py
+++ b/nova/network/manager.py
@@ -61,6 +61,7 @@ from nova import ipv6
from nova import manager
from nova.network import api as network_api
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
@@ -191,22 +192,12 @@ class RPCAllocateFixedIP(object):
host = network['host']
# NOTE(vish): if there is no network host, set one
if host is None:
- host = rpc.call(context, FLAGS.network_topic,
- {'method': 'set_network_host',
- 'args': {'network_ref':
- jsonutils.to_primitive(network)}})
+ host = self.network_rpcapi.set_network_host(context, network)
if host != self.host:
# need to call allocate_fixed_ip to correct network host
- topic = rpc.queue_get_for(context, FLAGS.network_topic, host)
- args = {}
- args['instance_id'] = instance_id
- args['network_id'] = network['id']
- args['address'] = address
- args['vpn'] = vpn
-
- green_pool.spawn_n(rpc.call, context, topic,
- {'method': '_rpc_allocate_fixed_ip',
- 'args': args})
+ green_pool.spawn_n(self.network_rpcapi._rpc_allocate_fixed_ip,
+ context, instance_id, network['id'], address, vpn,
+ host)
else:
# i am the correct host, run here
self.allocate_fixed_ip(context, instance_id, network,
@@ -235,12 +226,7 @@ class RPCAllocateFixedIP(object):
host = network['host']
if host != self.host:
# need to call deallocate_fixed_ip on correct network host
- topic = rpc.queue_get_for(context, FLAGS.network_topic, host)
- args = {'address': address,
- 'host': host}
- rpc.call(context, topic,
- {'method': 'deallocate_fixed_ip',
- 'args': args})
+ self.network_rpcapi.deallocate_fixed_ip(context, address, host)
else:
# i am the correct host, run here
super(RPCAllocateFixedIP, self).deallocate_fixed_ip(context,
@@ -534,12 +520,8 @@ class FloatingIP(object):
fixed_address, interface)
else:
# send to correct host
- rpc.call(context,
- rpc.queue_get_for(context, FLAGS.network_topic, host),
- {'method': '_associate_floating_ip',
- 'args': {'floating_address': floating_address,
- 'fixed_address': fixed_address,
- 'interface': interface}})
+ self.network_rpcapi._associate_floating_ip(context,
+ floating_address, fixed_address, interface, host)
return orig_instance_uuid
@@ -607,11 +589,8 @@ class FloatingIP(object):
self._disassociate_floating_ip(context, address, interface)
else:
# send to correct host
- rpc.call(context,
- rpc.queue_get_for(context, FLAGS.network_topic, host),
- {'method': '_disassociate_floating_ip',
- 'args': {'address': address,
- 'interface': interface}})
+ self.network_rpcapi._disassociate_floating_ip(context, address,
+ interface, host)
def _disassociate_floating_ip(self, context, address, interface):
"""Performs db and driver calls to disassociate floating ip"""
@@ -770,6 +749,8 @@ class NetworkManager(manager.SchedulerDependentManager):
The one at a time part is to flatten the layout to help scale
"""
+ RPC_API_VERSION = '1.0'
+
# If True, this manager requires VIF to create a bridge.
SHOULD_CREATE_BRIDGE = False
@@ -793,6 +774,7 @@ class NetworkManager(manager.SchedulerDependentManager):
self.floating_dns_manager = importutils.import_object(
FLAGS.floating_ip_dns_manager)
self.network_api = network_api.API()
+ self.network_rpcapi = network_rpcapi.NetworkAPI()
self.security_group_api = compute_api.SecurityGroupAPI()
self.compute_api = compute_api.API(
security_group_api=self.security_group_api)
@@ -1657,12 +1639,9 @@ class NetworkManager(manager.SchedulerDependentManager):
call_func(context, network)
else:
# i'm not the right host, run call on correct host
- topic = rpc.queue_get_for(context, FLAGS.network_topic, host)
- args = {'network_id': network['id'], 'teardown': teardown}
- # NOTE(tr3buchet): the call is just to wait for completion
- green_pool.spawn_n(rpc.call, context, topic,
- {'method': 'rpc_setup_network_on_host',
- 'args': args})
+ green_pool.spawn_n(
+ self.network_rpcapi.rpc_setup_network_on_host, context,
+ network['id'], teardown, host)
# wait for all of the setups (if any) to finish
green_pool.waitall()
diff --git a/nova/network/rpcapi.py b/nova/network/rpcapi.py
new file mode 100644
index 000000000..43c17acb5
--- /dev/null
+++ b/nova/network/rpcapi.py
@@ -0,0 +1,274 @@
+# vim: tabstop=4 shiftwidth=4 softtabstop=4
+
+# Copyright 2012, Red Hat, Inc.
+#
+# 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.
+
+"""
+Client side of the network RPC API.
+"""
+
+from nova import flags
+from nova.openstack.common import jsonutils
+from nova.openstack.common import rpc
+from nova.openstack.common.rpc import proxy as rpc_proxy
+
+
+FLAGS = flags.FLAGS
+
+
+class NetworkAPI(rpc_proxy.RpcProxy):
+ '''Client side of the network rpc API.
+
+ API version history:
+
+ 1.0 - Initial version.
+ '''
+
+ #
+ # NOTE(russellb): This is the default minimum version that the server
+ # (manager) side must implement unless otherwise specified using a version
+ # argument to self.call()/cast()/etc. here. It should be left as X.0 where
+ # X is the current major API version (1.0, 2.0, ...). For more information
+ # about rpc API versioning, see the docs in
+ # openstack/common/rpc/dispatcher.py.
+ #
+ BASE_RPC_API_VERSION = '1.0'
+
+ def __init__(self, topic=None):
+ topic = topic if topic else FLAGS.network_topic
+ super(NetworkAPI, self).__init__(
+ topic=topic,
+ default_version=self.BASE_RPC_API_VERSION)
+
+ def get_all_networks(self, ctxt):
+ return self.call(ctxt, self.make_msg('get_all_networks'))
+
+ def get_network(self, ctxt, network_uuid):
+ return self.call(ctxt, self.make_msg('get_network',
+ network_uuid=network_uuid))
+
+ # TODO(russellb): Convert this to named arguments. It's a pretty large
+ # list, so unwinding it all is probably best done in its own patch so it's
+ # easier to review.
+ def create_networks(self, ctxt, **kwargs):
+ return self.call(ctxt, self.make_msg('create_networks', **kwargs))
+
+ def delete_network(self, ctxt, uuid, fixed_range):
+ return self.call(ctxt, self.make_msg('delete_network',
+ uuid=uuid, fixed_range=fixed_range))
+
+ def disassociate_network(self, ctxt, network_uuid):
+ return self.call(ctxt, self.make_msg('disassociate_network',
+ network_uuid=network_uuid))
+
+ def get_fixed_ip(self, ctxt, id):
+ return self.call(ctxt, self.make_msg('get_fixed_ip', id=id))
+
+ def get_fixed_ip_by_address(self, ctxt, address):
+ return self.call(ctxt, self.make_msg('get_fixed_ip_by_address',
+ address=address))
+
+ def get_floating_ip(self, ctxt, id):
+ return self.call(ctxt, self.make_msg('get_floating_ip', id=id))
+
+ def get_floating_pools(self, ctxt):
+ return self.call(ctxt, self.make_msg('get_floating_pools'))
+
+ def get_floating_ip_by_address(self, ctxt, address):
+ return self.call(ctxt, self.make_msg('get_floating_ip_by_address',
+ address=address))
+
+ def get_floating_ips_by_project(self, ctxt):
+ return self.call(ctxt, self.make_msg('get_floating_ips_by_project'))
+
+ def get_floating_ips_by_fixed_address(self, ctxt, fixed_address):
+ return self.call(ctxt, self.make_msg(
+ 'get_floating_ips_by_fixed_address',
+ fixed_address=fixed_address))
+
+ def get_instance_id_by_floating_address(self, ctxt, address):
+ return self.call(ctxt, self.make_msg(
+ 'get_instance_id_by_floating_address',
+ address=address))
+
+ def get_vifs_by_instance(self, ctxt, instance_id):
+ # NOTE(vish): When the db calls are converted to store network
+ # data by instance_uuid, this should pass uuid instead.
+ return self.call(ctxt, self.make_msg('get_vifs_by_instance',
+ instance_id=instance_id))
+
+ def get_vif_by_mac_address(self, ctxt, mac_address):
+ return self.call(ctxt, self.make_msg('get_vif_by_mac_address',
+ mac_address=mac_address))
+
+ def allocate_floating_ip(self, ctxt, project_id, pool, auto_assigned):
+ return self.call(ctxt, self.make_msg('allocate_floating_ip',
+ project_id=project_id, pool=pool, auto_assigned=auto_assigned))
+
+ def deallocate_floating_ip(self, ctxt, address, affect_auto_assigned):
+ return self.call(ctxt, self.make_msg('deallocate_floating_ip',
+ address=address, affect_auto_assigned=affect_auto_assigned))
+
+ def associate_floating_ip(self, ctxt, floating_address, fixed_address,
+ affect_auto_assigned):
+ return self.call(ctxt, self.make_msg('associate_floating_ip',
+ floating_address=floating_address, fixed_address=fixed_address,
+ affect_auto_assigned=affect_auto_assigned))
+
+ def disassociate_floating_ip(self, ctxt, address, affect_auto_assigned):
+ return self.call(ctxt, self.make_msg('disassociate_floating_ip',
+ address=address, affect_auto_assigned=affect_auto_assigned))
+
+ def allocate_for_instance(self, ctxt, instance_id, instance_uuid,
+ project_id, host, rxtx_factor, vpn,
+ requested_networks):
+ return self.call(ctxt, self.make_msg('allocate_for_instance',
+ instance_id=instance_id, instance_uuid=instance_uuid,
+ project_id=project_id, host=host, rxtx_factor=rxtx_factor,
+ vpn=vpn, requested_networks=requested_networks))
+
+ def deallocate_for_instance(self, ctxt, instance_id, project_id, host):
+ return self.call(ctxt, self.make_msg('deallocate_for_instance',
+ instance_id=instance_id, project_id=project_id, host=host))
+
+ def add_fixed_ip_to_instance(self, ctxt, instance_id, host, network_id):
+ return self.call(ctxt, self.make_msg('add_fixed_ip_to_instance',
+ instance_id=instance_id, host=host, network_id=network_id))
+
+ def remove_fixed_ip_from_instance(self, ctxt, instance_id, host, address):
+ return self.call(ctxt, self.make_msg('remove_fixed_ip_from_instance',
+ instance_id=instance_id, host=host, address=address))
+
+ def add_network_to_project(self, ctxt, project_id, network_uuid):
+ return self.call(ctxt, self.make_msg('add_network_to_project',
+ project_id=project_id, network_uuid=network_uuid))
+
+ def get_instance_nw_info(self, ctxt, instance_id, instance_uuid,
+ rxtx_factor, host, project_id):
+ return self.call(ctxt, self.make_msg('get_instance_nw_info',
+ instance_id=instance_id, instance_uuid=instance_uuid,
+ rxtx_factor=rxtx_factor, host=host, project_id=project_id))
+
+ def validate_networks(self, ctxt, networks):
+ return self.call(ctxt, self.make_msg('validate_networks',
+ networks=networks))
+
+ def get_instance_uuids_by_ip_filter(self, ctxt, filters):
+ return self.call(ctxt, self.make_msg('get_instance_uuids_by_ip_filter',
+ filters=filters))
+
+ def get_dns_domains(self, ctxt):
+ return self.call(ctxt, self.make_msg('get_dns_domains'))
+
+ def add_dns_entry(self, ctxt, address, name, dns_type, domain):
+ return self.call(ctxt, self.make_msg('add_dns_entry', address=address,
+ name=name, dns_type=dns_type, domain=domain))
+
+ def modify_dns_entry(self, ctxt, address, name, domain):
+ return self.call(ctxt, self.make_msg('modify_dns_entry',
+ address=address, name=name, domain=domain))
+
+ def delete_dns_entry(self, ctxt, name, domain):
+ return self.call(ctxt, self.make_msg('delete_dns_entry',
+ name=name, domain=domain))
+
+ def delete_dns_domain(self, ctxt, domain):
+ return self.call(ctxt, self.make_msg('delete_dns_domain',
+ domain=domain))
+
+ def get_dns_entries_by_address(self, ctxt, address, domain):
+ return self.call(ctxt, self.make_msg('get_dns_entries_by_address',
+ address=address, domain=domain))
+
+ def get_dns_entries_by_name(self, ctxt, name, domain):
+ return self.call(ctxt, self.make_msg('get_dns_entries_by_name',
+ name=name, domain=domain))
+
+ def create_private_dns_domain(self, ctxt, domain, av_zone):
+ return self.call(ctxt, self.make_msg('create_private_dns_domain',
+ domain=domain, av_zone=av_zone))
+
+ def create_public_dns_domain(self, ctxt, domain, project):
+ return self.call(ctxt, self.make_msg('create_public_dns_domain',
+ domain=domain, project=project))
+
+ def setup_networks_on_host(self, ctxt, instance_id, host, teardown):
+ # NOTE(tr3buchet): the call is just to wait for completion
+ return self.call(ctxt, self.make_msg('setup_networks_on_host',
+ instance_id=instance_id, host=host, teardown=teardown))
+
+ def lease_fixed_ip(self, ctxt, host, address):
+ self.cast(ctxt, self.make_msg('lease_fixed_ip', address=address),
+ topic=rpc.queue_get_for(ctxt, self.topic, host))
+
+ def release_fixed_ip(self, ctxt, host, address):
+ self.cast(ctxt, self.make_msg('release_fixed_ip', address=address),
+ topic=rpc.queue_get_for(ctxt, self.topic, host))
+
+ def set_network_host(self, ctxt, network_ref):
+ network_ref_p = jsonutils.to_primitive(network_ref)
+ return self.call(ctxt, self.make_msg('set_network_host',
+ network_ref=network_ref_p))
+
+ def rpc_setup_network_on_host(self, ctxt, network_id, teardown, host):
+ # NOTE(tr3buchet): the call is just to wait for completion
+ return self.call(ctxt, self.make_msg('rpc_setup_network_on_host',
+ network_id=network_id, teardown=teardown),
+ topic=rpc.queue_get_for(ctxt, self.topic, host))
+
+ # NOTE(russellb): Ideally this would not have a prefix of '_' since it is
+ # a part of the rpc API. However, this is how it was being called when the
+ # 1.0 API was being documented using this client proxy class. It should be
+ # changed if there was ever a 2.0.
+ def _rpc_allocate_fixed_ip(self, ctxt, instance_id, network_id, address,
+ vpn, host):
+ return self.call(ctxt, self.make_msg('_rpc_allocate_fixed_ip',
+ instance_id=instance_id, network_id=network_id,
+ address=address, vpn=vpn),
+ topic=rpc.queue_get_for(ctxt, self.topic, host))
+
+ def deallocate_fixed_ip(self, ctxt, address, host):
+ return self.call(ctxt, self.make_msg('deallocate_fixed_ip',
+ address=address, host=host),
+ topic=rpc.queue_get_for(ctxt, self.topic, host))
+
+ # NOTE(russellb): Ideally this would not have a prefix of '_' since it is
+ # a part of the rpc API. However, this is how it was being called when the
+ # 1.0 API was being documented using this client proxy class. It should be
+ # changed if there was ever a 2.0.
+ def _associate_floating_ip(self, ctxt, floating_address, fixed_address,
+ interface, host):
+ return self.call(ctxt, self.make_msg('_associate_floating_ip',
+ floating_address=floating_address, fixed_address=fixed_address,
+ interface=interface),
+ topic=rpc.queue_get_for(ctxt, self.topic, host))
+
+ # NOTE(russellb): Ideally this would not have a prefix of '_' since it is
+ # a part of the rpc API. However, this is how it was being called when the
+ # 1.0 API was being documented using this client proxy class. It should be
+ # changed if there was ever a 2.0.
+ def _disassociate_floating_ip(self, ctxt, address, interface, host):
+ return self.call(ctxt, self.make_msg('_disassociate_floating_ip',
+ address=address, interface=interface),
+ topic=rpc.queue_get_for(ctxt, self.topic, host))
+
+ def lease_fixed_ip(self, ctxt, address, host):
+ return self.cast(ctxt, self.make_msg('lease_fixed_ip',
+ address=address),
+ topic=rpc.queue_get_for(ctxt, self.topic, host))
+
+ def release_fixed_ip(self, ctxt, address, host):
+ return self.cast(ctxt, self.make_msg('release_fixed_ip',
+ address=address),
+ topic=rpc.queue_get_for(ctxt, self.topic, host))
diff --git a/nova/tests/compute/test_compute.py b/nova/tests/compute/test_compute.py
index a5081066e..6fc317775 100644
--- a/nova/tests/compute/test_compute.py
+++ b/nova/tests/compute/test_compute.py
@@ -2160,7 +2160,8 @@ class ComputeTestCase(BaseTestCase):
rpc.call(c, 'network', {'method': 'setup_networks_on_host',
'args': {'instance_id': inst_id,
'host': self.compute.host,
- 'teardown': False}})
+ 'teardown': False},
+ 'version': '1.0'}, None)
rpcinst = jsonutils.to_primitive(
db.instance_get_by_uuid(self.context, instance['uuid']))
rpc.call(c, topic,
@@ -2255,7 +2256,8 @@ class ComputeTestCase(BaseTestCase):
rpc.call(c, 'network', {'method': 'setup_networks_on_host',
'args': {'instance_id': inst_id,
'host': self.compute.host,
- 'teardown': True}})
+ 'teardown': True},
+ 'version': '1.0'}, None)
# start test
self.mox.ReplayAll()
diff --git a/nova/tests/network/test_api.py b/nova/tests/network/test_api.py
index a29756caa..9bbd7ba92 100644
--- a/nova/tests/network/test_api.py
+++ b/nova/tests/network/test_api.py
@@ -35,7 +35,7 @@ class ApiTestCase(test.TestCase):
new_instance = {'uuid': 'new-uuid'}
- def fake_rpc_call(context, topic, msg):
+ def fake_rpc_call(context, topic, msg, timeout=None):
return orig_instance_uuid
self.stubs.Set(rpc, 'call', fake_rpc_call)
diff --git a/nova/tests/network/test_rpcapi.py b/nova/tests/network/test_rpcapi.py
new file mode 100644
index 000000000..a087ba97f
--- /dev/null
+++ b/nova/tests/network/test_rpcapi.py
@@ -0,0 +1,260 @@
+# vim: tabstop=4 shiftwidth=4 softtabstop=4
+
+# Copyright 2012, Red Hat, Inc.
+#
+# 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.
+
+"""
+Unit Tests for nova.network.rpcapi
+"""
+
+from nova import context
+from nova import flags
+from nova.network import rpcapi as network_rpcapi
+from nova.openstack.common import rpc
+from nova import test
+
+
+FLAGS = flags.FLAGS
+
+
+class NetworkRpcAPITestCase(test.TestCase):
+ def _test_network_api(self, method, rpc_method, **kwargs):
+ ctxt = context.RequestContext('fake_user', 'fake_project')
+ rpcapi = network_rpcapi.NetworkAPI()
+ expected_retval = 'foo' if method == 'call' else None
+ expected_version = kwargs.pop('version', rpcapi.BASE_RPC_API_VERSION)
+ expected_topic = FLAGS.network_topic
+ expected_msg = rpcapi.make_msg(method, **kwargs)
+ targeted_methods = [
+ 'lease_fixed_ip', 'release_fixed_ip', 'rpc_setup_network_on_host',
+ '_rpc_allocate_fixed_ip', 'deallocate_fixed_ip',
+ '_associate_floating_ip', '_disassociate_floating_ip',
+ 'lease_fixed_ip', 'release_fixed_ip'
+ ]
+ if method in targeted_methods and 'host' in kwargs:
+ if method != 'deallocate_fixed_ip':
+ del expected_msg['args']['host']
+ host = kwargs['host']
+ expected_topic = rpc.queue_get_for(ctxt, FLAGS.network_topic, host)
+ expected_msg['version'] = expected_version
+
+ self.fake_args = None
+ self.fake_kwargs = None
+
+ def _fake_rpc_method(*args, **kwargs):
+ self.fake_args = args
+ self.fake_kwargs = kwargs
+ if expected_retval:
+ return expected_retval
+
+ self.stubs.Set(rpc, rpc_method, _fake_rpc_method)
+
+ retval = getattr(rpcapi, method)(ctxt, **kwargs)
+
+ self.assertEqual(retval, expected_retval)
+ expected_args = [ctxt, expected_topic, expected_msg]
+ for arg, expected_arg in zip(self.fake_args, expected_args):
+ self.assertEqual(arg, expected_arg)
+
+ def test_get_all_networks(self):
+ self._test_network_api('get_all_networks', rpc_method='call')
+
+ def test_get_network(self):
+ self._test_network_api('get_network', rpc_method='call',
+ network_uuid='fake_uuid')
+
+ def test_create_networks(self):
+ self._test_network_api('create_networks', rpc_method='call',
+ arg1='arg', arg2='arg')
+
+ def test_delete_network(self):
+ self._test_network_api('delete_network', rpc_method='call',
+ uuid='fake_uuid', fixed_range='range')
+
+ def test_disassociate_network(self):
+ self._test_network_api('disassociate_network', rpc_method='call',
+ network_uuid='fake_uuid')
+
+ def test_get_fixed_ip(self):
+ self._test_network_api('get_fixed_ip', rpc_method='call', id='id')
+
+ def test_get_fixed_ip_by_address(self):
+ self._test_network_api('get_fixed_ip_by_address', rpc_method='call',
+ address='a.b.c.d')
+
+ def test_get_floating_ip(self):
+ self._test_network_api('get_floating_ip', rpc_method='call', id='id')
+
+ def test_get_floating_pools(self):
+ self._test_network_api('get_floating_pools', rpc_method='call')
+
+ def test_get_floating_ip_by_address(self):
+ self._test_network_api('get_floating_ip_by_address', rpc_method='call',
+ address='a.b.c.d')
+
+ def test_get_floating_ips_by_project(self):
+ self._test_network_api('get_floating_ips_by_project',
+ rpc_method='call')
+
+ def test_get_floating_ips_by_fixed_address(self):
+ self._test_network_api('get_floating_ips_by_fixed_address',
+ rpc_method='call', fixed_address='w.x.y.z')
+
+ def test_get_instance_id_by_floating_address(self):
+ self._test_network_api('get_instance_id_by_floating_address',
+ rpc_method='call', address='w.x.y.z')
+
+ def test_get_vifs_by_instance(self):
+ self._test_network_api('get_vifs_by_instance',
+ rpc_method='call', instance_id='fake_id')
+
+ def test_get_vif_by_mac_address(self):
+ self._test_network_api('get_vif_by_mac_address',
+ rpc_method='call', mac_address='fake_mac_addr')
+
+ def test_allocate_floating_ip(self):
+ self._test_network_api('allocate_floating_ip', rpc_method='call',
+ project_id='fake_id', pool='fake_pool', auto_assigned=False)
+
+ def test_deallocate_floating_ip(self):
+ self._test_network_api('deallocate_floating_ip', rpc_method='call',
+ address='addr', affect_auto_assigned=True)
+
+ def test_associate_floating_ip(self):
+ self._test_network_api('associate_floating_ip', rpc_method='call',
+ floating_address='blah', fixed_address='foo',
+ affect_auto_assigned=True)
+
+ def test_disassociate_floating_ip(self):
+ self._test_network_api('disassociate_floating_ip', rpc_method='call',
+ address='addr', affect_auto_assigned=True)
+
+ def test_allocate_for_instance(self):
+ self._test_network_api('allocate_for_instance', rpc_method='call',
+ instance_id='fake_id', instance_uuid='fake_uuid',
+ project_id='fake_id', host='fake_host',
+ rxtx_factor='fake_factor', vpn=False, requested_networks={})
+
+ def test_deallocate_for_instance(self):
+ self._test_network_api('deallocate_for_instance', rpc_method='call',
+ instance_id='fake_id', project_id='fake_id', host='fake_host')
+
+ def test_add_fixed_ip_to_instance(self):
+ self._test_network_api('add_fixed_ip_to_instance', rpc_method='call',
+ instance_id='fake_id', host='fake_host', network_id='fake_id')
+
+ def test_remove_fixed_ip_from_instance(self):
+ self._test_network_api('remove_fixed_ip_from_instance',
+ rpc_method='call', instance_id='fake_id', host='fake_host',
+ address='fake_address')
+
+ def test_add_network_to_project(self):
+ self._test_network_api('add_network_to_project', rpc_method='call',
+ project_id='fake_id', network_uuid='fake_uuid')
+
+ def test_get_instance_nw_info(self):
+ self._test_network_api('get_instance_nw_info', rpc_method='call',
+ instance_id='fake_id', instance_uuid='fake_uuid',
+ rxtx_factor='fake_factor', host='fake_host',
+ project_id='fake_id')
+
+ def test_validate_networks(self):
+ self._test_network_api('validate_networks', rpc_method='call',
+ networks={})
+
+ def test_get_instance_uuids_by_ip_filter(self):
+ self._test_network_api('get_instance_uuids_by_ip_filter',
+ rpc_method='call', filters={})
+
+ def test_get_dns_domains(self):
+ self._test_network_api('get_dns_domains', rpc_method='call')
+
+ def test_add_dns_entry(self):
+ self._test_network_api('add_dns_entry', rpc_method='call',
+ address='addr', name='name', dns_type='foo', domain='domain')
+
+ def test_modify_dns_entry(self):
+ self._test_network_api('modify_dns_entry', rpc_method='call',
+ address='addr', name='name', domain='domain')
+
+ def test_delete_dns_entry(self):
+ self._test_network_api('delete_dns_entry', rpc_method='call',
+ name='name', domain='domain')
+
+ def test_delete_dns_domain(self):
+ self._test_network_api('delete_dns_domain', rpc_method='call',
+ domain='fake_domain')
+
+ def test_get_dns_entries_by_address(self):
+ self._test_network_api('get_dns_entries_by_address', rpc_method='call',
+ address='fake_address', domain='fake_domain')
+
+ def test_get_dns_entries_by_name(self):
+ self._test_network_api('get_dns_entries_by_name', rpc_method='call',
+ name='fake_name', domain='fake_domain')
+
+ def test_create_private_dns_domain(self):
+ self._test_network_api('create_private_dns_domain', rpc_method='call',
+ domain='fake_domain', av_zone='fake_zone')
+
+ def test_create_public_dns_domain(self):
+ self._test_network_api('create_public_dns_domain', rpc_method='call',
+ domain='fake_domain', project='fake_project')
+
+ def test_setup_networks_on_host(self):
+ self._test_network_api('setup_networks_on_host', rpc_method='call',
+ instance_id='fake_id', host='fake_host', teardown=False)
+
+ def test_lease_fixed_ip(self):
+ self._test_network_api('lease_fixed_ip', rpc_method='cast',
+ host='fake_host', address='fake_addr')
+
+ def test_release_fixed_ip(self):
+ self._test_network_api('release_fixed_ip', rpc_method='cast',
+ host='fake_host', address='fake_addr')
+
+ def test_set_network_host(self):
+ self._test_network_api('set_network_host', rpc_method='call',
+ network_ref={})
+
+ def test_rpc_setup_network_on_host(self):
+ self._test_network_api('rpc_setup_network_on_host', rpc_method='call',
+ network_id='fake_id', teardown=False, host='fake_host')
+
+ def test_rpc_allocate_fixed_ip(self):
+ self._test_network_api('_rpc_allocate_fixed_ip', rpc_method='call',
+ instance_id='fake_id', network_id='fake_id', address='addr',
+ vpn=True, host='fake_host')
+
+ def test_deallocate_fixed_ip(self):
+ self._test_network_api('deallocate_fixed_ip', rpc_method='call',
+ address='fake_addr', host='fake_host')
+
+ def test__associate_floating_ip(self):
+ self._test_network_api('_associate_floating_ip', rpc_method='call',
+ floating_address='fake_addr', fixed_address='fixed_address',
+ interface='fake_interface', host='fake_host')
+
+ def test__disassociate_floating_ip(self):
+ self._test_network_api('_disassociate_floating_ip', rpc_method='call',
+ address='fake_addr', interface='fake_interface',
+ host='fake_host')
+
+ def test_lease_fixed_ip(self):
+ self._test_network_api('lease_fixed_ip', rpc_method='cast',
+ address='fake_addr', host='fake_host')
+
+ def test_release_fixed_ip(self):
+ self._test_network_api('release_fixed_ip', rpc_method='cast',
+ address='fake_addr', host='fake_host')