Support requested_networks with quantum v2.

Allow Quantum to attach instance only to selected networks, which can
be specified, for instance, via the --nic option on the nova CLI.

Fixes bug 1019899

Change-Id: I099056387edea9e3646cd4e329c76b674e03baa2
This commit is contained in:
Salvatore Orlando 2012-07-03 22:39:13 +01:00
parent 3f87856022
commit b1d5719556
3 changed files with 36 additions and 6 deletions

View File

@ -52,6 +52,8 @@
<rlane@wikimedia.org> <laner@controller>
<rnirmal@gmail.com> <nirmal.ranganathan@rackspace.com>
<rnirmal@gmail.com> <nirmal.ranganathan@rackspace.coom>
<salvatore.orlando@eu.citrix.com> <sorlando@nicira.com>
<salvatore.orlando@eu.citrix.com> <salv.orlando@gmail.com>
<sandy.walsh@rackspace.com> <sandy@sandywalsh.com>
<soren.hansen@rackspace.com> <soren@linux2go.dk>
<sorenhansen@rackspace.com> <sorhanse@cisco.com>

View File

@ -25,6 +25,7 @@ from nova.openstack.common import cfg
from nova.openstack.common import excutils
from nova.openstack.common import log as logging
quantum_opts = [
cfg.StrOpt('quantum_url',
default='http://127.0.0.1:9696',
@ -49,7 +50,6 @@ quantum_opts = [
FLAGS = flags.FLAGS
FLAGS.register_opts(quantum_opts)
LOG = logging.getLogger(__name__)
@ -71,6 +71,15 @@ class API(base.Base):
msg = _('empty project id for instance %s')
raise exception.InvalidInput(
reason=msg % instance['display_name'])
# If user has specified to attach instance only to specific
# networks, add them to **search_opts
# Tenant-only network only allowed so far
requested_networks = kwargs.get('requested_networks')
if requested_networks:
net_ids = [net_id for (net_id, _i) in requested_networks]
search_opts['id'] = net_ids
data = quantumv2.get_client(context).list_networks(**search_opts)
nets = data.get('networks', [])
created_port_ids = []

View File

@ -27,6 +27,7 @@ from nova import test
from nova import utils
from quantumclient.v2_0 import client
FLAGS = cfg.CONF
#NOTE: Quantum client raises Exception which is discouraged by HACKING.
# We set this variable here and use it for assertions below to avoid
@ -151,6 +152,10 @@ class TestQuantumv2(test.TestCase):
self.nets2.append({'id': 'my_netid2',
'name': 'my_netname2',
'tenant_id': 'my_tenantid'})
self.nets3 = self.nets2 + [{'id': 'my_netid3',
'name': 'my_netname3',
'tenant_id': 'my_tenantid'}]
self.nets = [self.nets1, self.nets2, self.nets3]
self.port_data1 = [{'network_id': 'my_netid1',
'device_id': 'device_id1',
@ -247,17 +252,23 @@ class TestQuantumv2(test.TestCase):
networks=self.nets1)
self._verify_nw_info(nw_inf, 0)
def _allocate_for_instance(self, number):
def _allocate_for_instance(self, net_idx=1, **kwargs):
api = quantumapi.API()
self.mox.StubOutWithMock(api, 'get_instance_nw_info')
nets = number == 1 and self.nets1 or self.nets2
# Net idx is 1-based for compatibility with existing unit tests
nets = self.nets[net_idx - 1]
api.get_instance_nw_info(mox.IgnoreArg(),
self.instance,
networks=nets).AndReturn(None)
mox_list_network_params = dict(tenant_id=self.instance['project_id'])
if 'requested_networks' in kwargs:
req_net_ids = [id for (id, _i) in kwargs['requested_networks']]
mox_list_network_params['id'] = [net['id'] for net in nets
if net['id'] in req_net_ids]
self.moxed_client.list_networks(
tenant_id=self.instance['project_id']).AndReturn(
{'networks': nets})
**mox_list_network_params).AndReturn({'networks': nets})
for network in nets:
port_req_body = {
'port': {
@ -271,7 +282,7 @@ class TestQuantumv2(test.TestCase):
self.moxed_client.create_port(
MyComparator(port_req_body)).AndReturn({'port': port})
self.mox.ReplayAll()
api.allocate_for_instance(self.context, self.instance)
api.allocate_for_instance(self.context, self.instance, **kwargs)
def test_allocate_for_instance_1(self):
"""Allocate one port in one network env."""
@ -281,6 +292,14 @@ class TestQuantumv2(test.TestCase):
"""Allocate one port in two networks env."""
self._allocate_for_instance(2)
def test_allocate_for_instance_with_requested_networks(self):
# specify only first and last network
requested_networks = [(net['id'], object())
for net in (self.nets3[0], self.nets3[-1])]
self._allocate_for_instance(net_idx=3,
requested_networks=requested_networks)
def test_allocate_for_instance_ex1(self):
"""verify we will delete created ports
if we fail to allocate all net resources.