merged trunk
This commit is contained in:
		
							
								
								
									
										1
									
								
								.mailmap
									
									
									
									
									
								
							
							
						
						
									
										1
									
								
								.mailmap
									
									
									
									
									
								
							@@ -15,6 +15,7 @@
 | 
			
		||||
<code@term.ie> <termie@preciousroy.local>
 | 
			
		||||
<corywright@gmail.com> <cory.wright@rackspace.com>
 | 
			
		||||
<dan@nicira.com> <danwent@dan-xs3-cs>
 | 
			
		||||
<dan@nicira.com> danwent@gmail.com
 | 
			
		||||
<devin.carlen@gmail.com> <devcamcar@illian.local>
 | 
			
		||||
<ewan.mellor@citrix.com> <emellor@silver>
 | 
			
		||||
<itoumsn@nttdata.co.jp> <itoumsn@shayol>
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										1
									
								
								Authors
									
									
									
									
									
								
							
							
						
						
									
										1
									
								
								Authors
									
									
									
									
									
								
							@@ -11,6 +11,7 @@ Antony Messerli <ant@openstack.org>
 | 
			
		||||
Armando Migliaccio <Armando.Migliaccio@eu.citrix.com>
 | 
			
		||||
Arvind Somya <asomya@cisco.com>
 | 
			
		||||
Bilal Akhtar <bilalakhtar@ubuntu.com>
 | 
			
		||||
Brad Hall <brad@nicira.com>
 | 
			
		||||
Brian Lamar <brian.lamar@rackspace.com>
 | 
			
		||||
Brian Schott <bschott@isi.edu>
 | 
			
		||||
Brian Waldon <brian.waldon@rackspace.com>
 | 
			
		||||
 
 | 
			
		||||
@@ -59,11 +59,11 @@ import glob
 | 
			
		||||
import json
 | 
			
		||||
import math
 | 
			
		||||
import netaddr
 | 
			
		||||
from optparse import OptionParser
 | 
			
		||||
import os
 | 
			
		||||
import sys
 | 
			
		||||
import time
 | 
			
		||||
 | 
			
		||||
from optparse import OptionParser
 | 
			
		||||
 | 
			
		||||
# If ../nova/__init__.py exists, add ../ to Python search path, so that
 | 
			
		||||
# it will override what happens to be installed in /usr/(local/)lib/python...
 | 
			
		||||
@@ -685,10 +685,17 @@ class NetworkCommands(object):
 | 
			
		||||
            help='Multi host')
 | 
			
		||||
    @args('--dns1', dest="dns1", metavar="<DNS Address>", help='First DNS')
 | 
			
		||||
    @args('--dns2', dest="dns2", metavar="<DNS Address>", help='Second DNS')
 | 
			
		||||
    @args('--uuid', dest="net_uuid", metavar="<network uuid>",
 | 
			
		||||
      help='Network UUID')
 | 
			
		||||
    @args('--project_id', dest="project_id", metavar="<project id>",
 | 
			
		||||
      help='Project id')
 | 
			
		||||
    @args('--priority', dest="priority", metavar="<number>",
 | 
			
		||||
      help='Network interface priority')
 | 
			
		||||
    def create(self, label=None, fixed_range_v4=None, num_networks=None,
 | 
			
		||||
               network_size=None, multi_host=None, vlan_start=None,
 | 
			
		||||
               vpn_start=None, fixed_range_v6=None, gateway_v6=None,
 | 
			
		||||
               bridge=None, bridge_interface=None, dns1=None, dns2=None):
 | 
			
		||||
               bridge=None, bridge_interface=None, dns1=None, dns2=None,
 | 
			
		||||
               project_id=None, priority=None, uuid=None):
 | 
			
		||||
        """Creates fixed ips for host by range"""
 | 
			
		||||
 | 
			
		||||
        # check for certain required inputs
 | 
			
		||||
@@ -765,7 +772,10 @@ class NetworkCommands(object):
 | 
			
		||||
                                    bridge=bridge,
 | 
			
		||||
                                    bridge_interface=bridge_interface,
 | 
			
		||||
                                    dns1=dns1,
 | 
			
		||||
                                    dns2=dns2)
 | 
			
		||||
                                    dns2=dns2,
 | 
			
		||||
                                    project_id=project_id,
 | 
			
		||||
                                    priority=priority,
 | 
			
		||||
                                    uuid=uuid)
 | 
			
		||||
 | 
			
		||||
    def list(self):
 | 
			
		||||
        """List all created networks"""
 | 
			
		||||
@@ -790,16 +800,29 @@ class NetworkCommands(object):
 | 
			
		||||
                          network.project_id,
 | 
			
		||||
                          network.uuid)
 | 
			
		||||
 | 
			
		||||
    def quantum_list(self):
 | 
			
		||||
        """List all created networks with Quantum-relevant fields"""
 | 
			
		||||
        _fmt = "%-32s\t%-10s\t%-10s\t%s , %s"
 | 
			
		||||
        print _fmt % (_('uuid'),
 | 
			
		||||
                      _('project'),
 | 
			
		||||
                      _('priority'),
 | 
			
		||||
                      _('cidr_v4'),
 | 
			
		||||
                      _('cidr_v6'))
 | 
			
		||||
        for network in db.network_get_all(context.get_admin_context()):
 | 
			
		||||
            print _fmt % (network.uuid,
 | 
			
		||||
                          network.project_id,
 | 
			
		||||
                          network.priority,
 | 
			
		||||
                          network.cidr,
 | 
			
		||||
                          network.cidr_v6)
 | 
			
		||||
 | 
			
		||||
    @args('--network', dest="fixed_range", metavar='<x.x.x.x/yy>',
 | 
			
		||||
            help='Network to delete')
 | 
			
		||||
    def delete(self, fixed_range):
 | 
			
		||||
        """Deletes a network"""
 | 
			
		||||
        network = db.network_get_by_cidr(context.get_admin_context(), \
 | 
			
		||||
                                         fixed_range)
 | 
			
		||||
        if network.project_id is not None:
 | 
			
		||||
            raise ValueError(_('Network must be disassociated from project %s'
 | 
			
		||||
                               ' before delete' % network.project_id))
 | 
			
		||||
        db.network_delete_safe(context.get_admin_context(), network.id)
 | 
			
		||||
 | 
			
		||||
        # delete the network
 | 
			
		||||
        net_manager = utils.import_object(FLAGS.network_manager)
 | 
			
		||||
        net_manager.delete_network(context.get_admin_context(), fixed_range)
 | 
			
		||||
 | 
			
		||||
    @args('--network', dest="fixed_range", metavar='<x.x.x.x/yy>',
 | 
			
		||||
            help='Network to modify')
 | 
			
		||||
 
 | 
			
		||||
@@ -435,6 +435,10 @@ class NetworkNotFoundForBridge(NetworkNotFound):
 | 
			
		||||
    message = _("Network could not be found for bridge %(bridge)s")
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class NetworkNotFoundForUUID(NetworkNotFound):
 | 
			
		||||
    message = _("Network could not be found for uuid %(uuid)s")
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class NetworkNotFoundForCidr(NetworkNotFound):
 | 
			
		||||
    message = _("Network could not be found with cidr %(cidr)s.")
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -55,5 +55,17 @@ class BaseScheduler(abstract_scheduler.AbstractScheduler):
 | 
			
		||||
        scheduling objectives
 | 
			
		||||
        """
 | 
			
		||||
        # NOTE(sirp): The default logic is the same as the NoopCostFunction
 | 
			
		||||
        return [dict(weight=1, hostname=hostname, capabilities=capabilities)
 | 
			
		||||
        hosts = [dict(weight=1, hostname=hostname, capabilities=capabilities)
 | 
			
		||||
                 for hostname, capabilities in hosts]
 | 
			
		||||
 | 
			
		||||
        # NOTE(Vek): What we actually need to return is enough hosts
 | 
			
		||||
        #            for all the instances!
 | 
			
		||||
        num_instances = request_spec.get('num_instances', 1)
 | 
			
		||||
        instances = []
 | 
			
		||||
        while num_instances > len(hosts):
 | 
			
		||||
            instances.extend(hosts)
 | 
			
		||||
            num_instances -= len(hosts)
 | 
			
		||||
        if num_instances > 0:
 | 
			
		||||
            instances.extend(hosts[:num_instances])
 | 
			
		||||
 | 
			
		||||
        return instances
 | 
			
		||||
 
 | 
			
		||||
@@ -26,6 +26,7 @@ from nova import test
 | 
			
		||||
from nova.compute import api as compute_api
 | 
			
		||||
from nova.scheduler import driver
 | 
			
		||||
from nova.scheduler import abstract_scheduler
 | 
			
		||||
from nova.scheduler import base_scheduler
 | 
			
		||||
from nova.scheduler import zone_manager
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@@ -65,6 +66,11 @@ class FakeAbstractScheduler(abstract_scheduler.AbstractScheduler):
 | 
			
		||||
    pass
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class FakeBaseScheduler(base_scheduler.BaseScheduler):
 | 
			
		||||
    # No need to stub anything at the moment
 | 
			
		||||
    pass
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class FakeZoneManager(zone_manager.ZoneManager):
 | 
			
		||||
    def __init__(self):
 | 
			
		||||
        self.service_states = {
 | 
			
		||||
@@ -387,3 +393,30 @@ class AbstractSchedulerTestCase(test.TestCase):
 | 
			
		||||
 | 
			
		||||
        # 0 from local zones, 12 from remotes
 | 
			
		||||
        self.assertEqual(12, len(build_plan))
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class BaseSchedulerTestCase(test.TestCase):
 | 
			
		||||
    """Test case for Base Scheduler."""
 | 
			
		||||
 | 
			
		||||
    def test_weigh_hosts(self):
 | 
			
		||||
        """
 | 
			
		||||
        Try to weigh a short list of hosts and make sure enough
 | 
			
		||||
        entries for a larger number instances are returned.
 | 
			
		||||
        """
 | 
			
		||||
 | 
			
		||||
        sched = FakeBaseScheduler()
 | 
			
		||||
 | 
			
		||||
        # Fake out a list of hosts
 | 
			
		||||
        zm = FakeZoneManager()
 | 
			
		||||
        hostlist = [(host, services['compute'])
 | 
			
		||||
                    for host, services in zm.service_states.items()
 | 
			
		||||
                    if 'compute' in services]
 | 
			
		||||
 | 
			
		||||
        # Call weigh_hosts()
 | 
			
		||||
        num_instances = len(hostlist) * 2 + len(hostlist) / 2
 | 
			
		||||
        instlist = sched.weigh_hosts('compute',
 | 
			
		||||
                                     dict(num_instances=num_instances),
 | 
			
		||||
                                     hostlist)
 | 
			
		||||
 | 
			
		||||
        # Should be enough entries to cover all instances
 | 
			
		||||
        self.assertEqual(len(instlist), num_instances)
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										323
									
								
								nova/tests/test_quantum.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										323
									
								
								nova/tests/test_quantum.py
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,323 @@
 | 
			
		||||
# vim: tabstop=4 shiftwidth=4 softtabstop=4
 | 
			
		||||
 | 
			
		||||
# Copyright 2011 Nicira, Inc.
 | 
			
		||||
# 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 db
 | 
			
		||||
from nova.db.sqlalchemy import models
 | 
			
		||||
from nova.db.sqlalchemy.session import get_session
 | 
			
		||||
from nova import exception
 | 
			
		||||
from nova import ipv6
 | 
			
		||||
from nova import log as logging
 | 
			
		||||
from nova.network.quantum import manager as quantum_manager
 | 
			
		||||
from nova import test
 | 
			
		||||
from nova import utils
 | 
			
		||||
 | 
			
		||||
LOG = logging.getLogger('nova.tests.quantum_network')
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
# this class can be used for unit functional/testing on nova,
 | 
			
		||||
# as it does not actually make remote calls to the Quantum service
 | 
			
		||||
class FakeQuantumClientConnection(object):
 | 
			
		||||
 | 
			
		||||
    def __init__(self):
 | 
			
		||||
        self.nets = {}
 | 
			
		||||
 | 
			
		||||
    def get_networks_for_tenant(self, tenant_id):
 | 
			
		||||
        net_ids = []
 | 
			
		||||
        for net_id, n in self.nets.items():
 | 
			
		||||
            if n['tenant-id'] == tenant_id:
 | 
			
		||||
                net_ids.append(net_id)
 | 
			
		||||
        return net_ids
 | 
			
		||||
 | 
			
		||||
    def create_network(self, tenant_id, network_name):
 | 
			
		||||
 | 
			
		||||
        uuid = str(utils.gen_uuid())
 | 
			
		||||
        self.nets[uuid] = {'net-name': network_name,
 | 
			
		||||
                           'tenant-id': tenant_id,
 | 
			
		||||
                           'ports': {}}
 | 
			
		||||
        return uuid
 | 
			
		||||
 | 
			
		||||
    def delete_network(self, tenant_id, net_id):
 | 
			
		||||
        if self.nets[net_id]['tenant-id'] == tenant_id:
 | 
			
		||||
            del self.nets[net_id]
 | 
			
		||||
 | 
			
		||||
    def network_exists(self, tenant_id, net_id):
 | 
			
		||||
        try:
 | 
			
		||||
            return self.nets[net_id]['tenant-id'] == tenant_id
 | 
			
		||||
        except KeyError:
 | 
			
		||||
            return False
 | 
			
		||||
 | 
			
		||||
    def _confirm_not_attached(self, interface_id):
 | 
			
		||||
        for n in self.nets.values():
 | 
			
		||||
            for p in n['ports'].values():
 | 
			
		||||
                if p['attachment-id'] == interface_id:
 | 
			
		||||
                    raise Exception(_("interface '%s' is already attached" %
 | 
			
		||||
                                          interface_id))
 | 
			
		||||
 | 
			
		||||
    def create_and_attach_port(self, tenant_id, net_id, interface_id):
 | 
			
		||||
        if not self.network_exists(tenant_id, net_id):
 | 
			
		||||
            raise Exception(
 | 
			
		||||
                _("network %(net_id)s does not exist for tenant %(tenant_id)"
 | 
			
		||||
                    % locals()))
 | 
			
		||||
 | 
			
		||||
        self._confirm_not_attached(interface_id)
 | 
			
		||||
        uuid = str(utils.gen_uuid())
 | 
			
		||||
        self.nets[net_id]['ports'][uuid] = \
 | 
			
		||||
                {"port-state": "ACTIVE",
 | 
			
		||||
                "attachment-id": interface_id}
 | 
			
		||||
 | 
			
		||||
    def detach_and_delete_port(self, tenant_id, net_id, port_id):
 | 
			
		||||
        if not self.network_exists(tenant_id, net_id):
 | 
			
		||||
            raise exception.NotFound(
 | 
			
		||||
                    _("network %(net_id)s does not exist "
 | 
			
		||||
                        "for tenant %(tenant_id)s" % locals()))
 | 
			
		||||
        del self.nets[net_id]['ports'][port_id]
 | 
			
		||||
 | 
			
		||||
    def get_port_by_attachment(self, tenant_id, attachment_id):
 | 
			
		||||
        for net_id, n in self.nets.items():
 | 
			
		||||
            if n['tenant-id'] == tenant_id:
 | 
			
		||||
                for port_id, p in n['ports'].items():
 | 
			
		||||
                    if p['attachment-id'] == attachment_id:
 | 
			
		||||
                        return (net_id, port_id)
 | 
			
		||||
 | 
			
		||||
        return (None, None)
 | 
			
		||||
 | 
			
		||||
networks = [{'label': 'project1-net1',
 | 
			
		||||
             'injected': False,
 | 
			
		||||
             'multi_host': False,
 | 
			
		||||
             'cidr': '192.168.0.0/24',
 | 
			
		||||
             'cidr_v6': '2001:1db8::/64',
 | 
			
		||||
             'gateway_v6': '2001:1db8::1',
 | 
			
		||||
             'netmask_v6': '64',
 | 
			
		||||
             'netmask': '255.255.255.0',
 | 
			
		||||
             'bridge': None,
 | 
			
		||||
             'bridge_interface': None,
 | 
			
		||||
             'gateway': '192.168.0.1',
 | 
			
		||||
             'broadcast': '192.168.0.255',
 | 
			
		||||
             'dns1': '192.168.0.1',
 | 
			
		||||
             'dns2': '192.168.0.2',
 | 
			
		||||
             'vlan': None,
 | 
			
		||||
             'host': None,
 | 
			
		||||
             'vpn_public_address': None,
 | 
			
		||||
             'project_id': 'fake_project1',
 | 
			
		||||
             'priority': 1},
 | 
			
		||||
            {'label': 'project2-net1',
 | 
			
		||||
             'injected': False,
 | 
			
		||||
             'multi_host': False,
 | 
			
		||||
             'cidr': '192.168.1.0/24',
 | 
			
		||||
             'cidr_v6': '2001:1db9::/64',
 | 
			
		||||
             'gateway_v6': '2001:1db9::1',
 | 
			
		||||
             'netmask_v6': '64',
 | 
			
		||||
             'netmask': '255.255.255.0',
 | 
			
		||||
             'bridge': None,
 | 
			
		||||
             'bridge_interface': None,
 | 
			
		||||
             'gateway': '192.168.1.1',
 | 
			
		||||
             'broadcast': '192.168.1.255',
 | 
			
		||||
             'dns1': '192.168.0.1',
 | 
			
		||||
             'dns2': '192.168.0.2',
 | 
			
		||||
             'vlan': None,
 | 
			
		||||
             'host': None,
 | 
			
		||||
             'project_id': 'fake_project2',
 | 
			
		||||
             'priority': 1},
 | 
			
		||||
             {'label': "public",
 | 
			
		||||
             'injected': False,
 | 
			
		||||
             'multi_host': False,
 | 
			
		||||
             'cidr': '10.0.0.0/24',
 | 
			
		||||
             'cidr_v6': '2001:1dba::/64',
 | 
			
		||||
             'gateway_v6': '2001:1dba::1',
 | 
			
		||||
             'netmask_v6': '64',
 | 
			
		||||
             'netmask': '255.255.255.0',
 | 
			
		||||
             'bridge': None,
 | 
			
		||||
             'bridge_interface': None,
 | 
			
		||||
             'gateway': '10.0.0.1',
 | 
			
		||||
             'broadcast': '10.0.0.255',
 | 
			
		||||
             'dns1': '10.0.0.1',
 | 
			
		||||
             'dns2': '10.0.0.2',
 | 
			
		||||
             'vlan': None,
 | 
			
		||||
             'host': None,
 | 
			
		||||
             'project_id': None,
 | 
			
		||||
             'priority': 0},
 | 
			
		||||
             {'label': "project2-net2",
 | 
			
		||||
             'injected': False,
 | 
			
		||||
             'multi_host': False,
 | 
			
		||||
             'cidr': '9.0.0.0/24',
 | 
			
		||||
             'cidr_v6': '2001:1dbb::/64',
 | 
			
		||||
             'gateway_v6': '2001:1dbb::1',
 | 
			
		||||
             'netmask_v6': '64',
 | 
			
		||||
             'netmask': '255.255.255.0',
 | 
			
		||||
             'bridge': None,
 | 
			
		||||
             'bridge_interface': None,
 | 
			
		||||
             'gateway': '9.0.0.1',
 | 
			
		||||
             'broadcast': '9.0.0.255',
 | 
			
		||||
             'dns1': '9.0.0.1',
 | 
			
		||||
             'dns2': '9.0.0.2',
 | 
			
		||||
             'vlan': None,
 | 
			
		||||
             'host': None,
 | 
			
		||||
             'project_id': "fake_project2",
 | 
			
		||||
             'priority': 2}]
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
# this is a base class to be used by all other Quantum Test classes
 | 
			
		||||
class QuantumTestCaseBase(object):
 | 
			
		||||
 | 
			
		||||
    def test_create_and_delete_nets(self):
 | 
			
		||||
        self._create_nets()
 | 
			
		||||
        self._delete_nets()
 | 
			
		||||
 | 
			
		||||
    def _create_nets(self):
 | 
			
		||||
        for n in networks:
 | 
			
		||||
            ctx = context.RequestContext('user1', n['project_id'])
 | 
			
		||||
            self.net_man.create_networks(ctx,
 | 
			
		||||
                    label=n['label'], cidr=n['cidr'],
 | 
			
		||||
                    multi_host=n['multi_host'],
 | 
			
		||||
                    num_networks=1, network_size=256, cidr_v6=n['cidr_v6'],
 | 
			
		||||
                    gateway_v6=n['gateway_v6'], bridge=None,
 | 
			
		||||
                    bridge_interface=None, dns1=n['dns1'],
 | 
			
		||||
                    dns2=n['dns2'], project_id=n['project_id'],
 | 
			
		||||
                    priority=n['priority'])
 | 
			
		||||
 | 
			
		||||
    def _delete_nets(self):
 | 
			
		||||
        for n in networks:
 | 
			
		||||
            ctx = context.RequestContext('user1', n['project_id'])
 | 
			
		||||
            self.net_man.delete_network(ctx, n['cidr'])
 | 
			
		||||
 | 
			
		||||
    def test_allocate_and_deallocate_instance_static(self):
 | 
			
		||||
        self._create_nets()
 | 
			
		||||
 | 
			
		||||
        project_id = "fake_project1"
 | 
			
		||||
        ctx = context.RequestContext('user1', project_id)
 | 
			
		||||
 | 
			
		||||
        instance_ref = db.api.instance_create(ctx,
 | 
			
		||||
                                    {"project_id": project_id})
 | 
			
		||||
        nw_info = self.net_man.allocate_for_instance(ctx,
 | 
			
		||||
                        instance_id=instance_ref['id'], host="",
 | 
			
		||||
                        instance_type_id=instance_ref['instance_type_id'],
 | 
			
		||||
                        project_id=project_id)
 | 
			
		||||
 | 
			
		||||
        self.assertEquals(len(nw_info), 2)
 | 
			
		||||
 | 
			
		||||
        # we don't know which order the NICs will be in until we
 | 
			
		||||
        # introduce the notion of priority
 | 
			
		||||
        # v4 cidr
 | 
			
		||||
        self.assertTrue(nw_info[0][0]['cidr'].startswith("10."))
 | 
			
		||||
        self.assertTrue(nw_info[1][0]['cidr'].startswith("192."))
 | 
			
		||||
 | 
			
		||||
        # v4 address
 | 
			
		||||
        self.assertTrue(nw_info[0][1]['ips'][0]['ip'].startswith("10."))
 | 
			
		||||
        self.assertTrue(nw_info[1][1]['ips'][0]['ip'].startswith("192."))
 | 
			
		||||
 | 
			
		||||
        # v6 cidr
 | 
			
		||||
        self.assertTrue(nw_info[0][0]['cidr_v6'].startswith("2001:1dba:"))
 | 
			
		||||
        self.assertTrue(nw_info[1][0]['cidr_v6'].startswith("2001:1db8:"))
 | 
			
		||||
 | 
			
		||||
        # v6 address
 | 
			
		||||
        self.assertTrue(
 | 
			
		||||
            nw_info[0][1]['ip6s'][0]['ip'].startswith("2001:1dba:"))
 | 
			
		||||
        self.assertTrue(
 | 
			
		||||
            nw_info[1][1]['ip6s'][0]['ip'].startswith("2001:1db8:"))
 | 
			
		||||
 | 
			
		||||
        self.net_man.deallocate_for_instance(ctx,
 | 
			
		||||
                    instance_id=instance_ref['id'],
 | 
			
		||||
                    project_id=project_id)
 | 
			
		||||
 | 
			
		||||
        self._delete_nets()
 | 
			
		||||
 | 
			
		||||
    def test_allocate_and_deallocate_instance_dynamic(self):
 | 
			
		||||
        self._create_nets()
 | 
			
		||||
        project_id = "fake_project2"
 | 
			
		||||
        ctx = context.RequestContext('user1', project_id)
 | 
			
		||||
 | 
			
		||||
        net_ids = self.net_man.q_conn.get_networks_for_tenant(project_id)
 | 
			
		||||
        requested_networks = [(net_id, None) for net_id in net_ids]
 | 
			
		||||
 | 
			
		||||
        self.net_man.validate_networks(ctx, requested_networks)
 | 
			
		||||
 | 
			
		||||
        instance_ref = db.api.instance_create(ctx,
 | 
			
		||||
                                    {"project_id": project_id})
 | 
			
		||||
        nw_info = self.net_man.allocate_for_instance(ctx,
 | 
			
		||||
                        instance_id=instance_ref['id'], host="",
 | 
			
		||||
                        instance_type_id=instance_ref['instance_type_id'],
 | 
			
		||||
                        project_id=project_id,
 | 
			
		||||
                        requested_networks=requested_networks)
 | 
			
		||||
 | 
			
		||||
        self.assertEquals(len(nw_info), 2)
 | 
			
		||||
 | 
			
		||||
        # we don't know which order the NICs will be in until we
 | 
			
		||||
        # introduce the notion of priority
 | 
			
		||||
        # v4 cidr
 | 
			
		||||
        self.assertTrue(nw_info[0][0]['cidr'].startswith("9.") or
 | 
			
		||||
                        nw_info[1][0]['cidr'].startswith("9."))
 | 
			
		||||
        self.assertTrue(nw_info[0][0]['cidr'].startswith("192.") or
 | 
			
		||||
                        nw_info[1][0]['cidr'].startswith("192."))
 | 
			
		||||
 | 
			
		||||
        # v4 address
 | 
			
		||||
        self.assertTrue(nw_info[0][1]['ips'][0]['ip'].startswith("9.") or
 | 
			
		||||
                        nw_info[1][1]['ips'][0]['ip'].startswith("9."))
 | 
			
		||||
        self.assertTrue(nw_info[0][1]['ips'][0]['ip'].startswith("192.") or
 | 
			
		||||
                        nw_info[1][1]['ips'][0]['ip'].startswith("192."))
 | 
			
		||||
 | 
			
		||||
        # v6 cidr
 | 
			
		||||
        self.assertTrue(nw_info[0][0]['cidr_v6'].startswith("2001:1dbb:") or
 | 
			
		||||
                        nw_info[1][0]['cidr_v6'].startswith("2001:1dbb:"))
 | 
			
		||||
        self.assertTrue(nw_info[0][0]['cidr_v6'].startswith("2001:1db9:") or
 | 
			
		||||
                        nw_info[1][0]['cidr_v6'].startswith("2001:1db9:"))
 | 
			
		||||
 | 
			
		||||
        # v6 address
 | 
			
		||||
        self.assertTrue(
 | 
			
		||||
            nw_info[0][1]['ip6s'][0]['ip'].startswith("2001:1dbb:") or
 | 
			
		||||
            nw_info[1][1]['ip6s'][0]['ip'].startswith("2001:1dbb:"))
 | 
			
		||||
        self.assertTrue(
 | 
			
		||||
            nw_info[0][1]['ip6s'][0]['ip'].startswith("2001:1db9:") or
 | 
			
		||||
            nw_info[1][1]['ip6s'][0]['ip'].startswith("2001:1db9:"))
 | 
			
		||||
 | 
			
		||||
        self.net_man.deallocate_for_instance(ctx,
 | 
			
		||||
                    instance_id=instance_ref['id'],
 | 
			
		||||
                    project_id=project_id)
 | 
			
		||||
 | 
			
		||||
        self._delete_nets()
 | 
			
		||||
 | 
			
		||||
    def test_validate_bad_network(self):
 | 
			
		||||
        ctx = context.RequestContext('user1', 'fake_project1')
 | 
			
		||||
        self.assertRaises(exception.NetworkNotFound,
 | 
			
		||||
                        self.net_man.validate_networks, ctx, [("", None)])
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class QuantumNovaIPAMTestCase(QuantumTestCaseBase, test.TestCase):
 | 
			
		||||
 | 
			
		||||
    def setUp(self):
 | 
			
		||||
        super(QuantumNovaIPAMTestCase, self).setUp()
 | 
			
		||||
 | 
			
		||||
        self.net_man = quantum_manager.QuantumManager(
 | 
			
		||||
                ipam_lib="nova.network.quantum.nova_ipam_lib",
 | 
			
		||||
                q_conn=FakeQuantumClientConnection())
 | 
			
		||||
 | 
			
		||||
        # Tests seem to create some networks by default, which
 | 
			
		||||
        # we don't want.  So we delete them.
 | 
			
		||||
 | 
			
		||||
        ctx = context.RequestContext('user1', 'fake_project1').elevated()
 | 
			
		||||
        for n in db.network_get_all(ctx):
 | 
			
		||||
            db.network_delete_safe(ctx, n['id'])
 | 
			
		||||
 | 
			
		||||
        # Other unit tests (e.g., test_compute.py) have a nasty
 | 
			
		||||
        # habit of of creating fixed IPs and not cleaning up, which
 | 
			
		||||
        # can confuse these tests, so we remove all existing fixed
 | 
			
		||||
        # ips before starting.
 | 
			
		||||
        session = get_session()
 | 
			
		||||
        result = session.query(models.FixedIp).all()
 | 
			
		||||
        with session.begin():
 | 
			
		||||
            for fip_ref in result:
 | 
			
		||||
                session.delete(fip_ref)
 | 
			
		||||
		Reference in New Issue
	
	Block a user