~ubuntu-branches/ubuntu/quantal/nova/quantal-proposed

« back to all changes in this revision

Viewing changes to nova/tests/network/test_quantum.py

  • Committer: Package Import Robot
  • Author(s): Chuck Short
  • Date: 2012-08-16 14:04:11 UTC
  • mto: This revision was merged to the branch mainline in revision 84.
  • Revision ID: package-import@ubuntu.com-20120816140411-0mr4n241wmk30t9l
Tags: upstream-2012.2~f3
ImportĀ upstreamĀ versionĀ 2012.2~f3

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# vim: tabstop=4 shiftwidth=4 softtabstop=4
2
 
 
3
 
# Copyright 2011,2012 Nicira, Inc.
4
 
# All Rights Reserved.
5
 
#
6
 
# Licensed under the Apache License, Version 2.0 (the "License"); you may
7
 
# not use this file except in compliance with the License. You may obtain
8
 
# a copy of the License at
9
 
#
10
 
#      http://www.apache.org/licenses/LICENSE-2.0
11
 
#
12
 
# Unless required by applicable law or agreed to in writing, software
13
 
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
14
 
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
15
 
# License for the specific language governing permissions and limitations
16
 
# under the License.
17
 
 
18
 
import mox
19
 
 
20
 
from nova import context
21
 
from nova import db
22
 
from nova.db.sqlalchemy import models
23
 
from nova.db.sqlalchemy import session as sql_session
24
 
from nova import exception
25
 
from nova import flags
26
 
from nova.network.quantum import client as quantum_client
27
 
from nova.network.quantum import fake_client
28
 
from nova.network.quantum import manager as quantum_manager
29
 
from nova.network.quantum import melange_connection
30
 
from nova.network.quantum import melange_ipam_lib
31
 
from nova.network.quantum import quantum_connection
32
 
from nova.openstack.common import log as logging
33
 
 
34
 
from nova import test
35
 
from nova import utils
36
 
 
37
 
LOG = logging.getLogger(__name__)
38
 
FLAGS = flags.FLAGS
39
 
 
40
 
 
41
 
networks = [{'label': 'project1-net1',
42
 
             'injected': False,
43
 
             'multi_host': False,
44
 
             'cidr': '100.168.0.0/24',
45
 
             'cidr_v6': '100:1db8::/64',
46
 
             'gateway_v6': '100:1db8::1',
47
 
             'netmask_v6': '64',
48
 
             'netmask': '255.255.255.0',
49
 
             'bridge': None,
50
 
             'bridge_interface': None,
51
 
             'gateway': '100.168.0.1',
52
 
             'broadcast': '100.168.0.255',
53
 
             'dns1': '8.8.8.8',
54
 
             'vlan': None,
55
 
             'host': None,
56
 
             'vpn_public_address': None,
57
 
             'project_id': 'fake_project1',
58
 
             'priority': 1},
59
 
            {'label': 'project2-net1',
60
 
             'injected': False,
61
 
             'multi_host': False,
62
 
             'cidr': '101.168.1.0/24',
63
 
             'cidr_v6': '101:1db9::/64',
64
 
             'gateway_v6': '101:1db9::1',
65
 
             'netmask_v6': '64',
66
 
             'netmask': '255.255.255.0',
67
 
             'bridge': None,
68
 
             'bridge_interface': None,
69
 
             'gateway': '101.168.1.1',
70
 
             'broadcast': '101.168.1.255',
71
 
             'dns1': '8.8.8.8',
72
 
             'vlan': None,
73
 
             'host': None,
74
 
             'project_id': 'fake_project2',
75
 
             'priority': 1},
76
 
             {'label': "public",
77
 
             'injected': False,
78
 
             'multi_host': False,
79
 
             'cidr': '102.0.0.0/24',
80
 
             'cidr_v6': '102:1dba::/64',
81
 
             'gateway_v6': '102:1dba::1',
82
 
             'netmask_v6': '64',
83
 
             'netmask': '255.255.255.0',
84
 
             'bridge': None,
85
 
             'bridge_interface': None,
86
 
             'gateway': '102.0.0.1',
87
 
             'broadcast': '102.0.0.255',
88
 
             'dns1': '8.8.8.8',
89
 
             'vlan': None,
90
 
             'host': None,
91
 
             'project_id': None,
92
 
             'priority': 0},
93
 
             {'label': "project2-net2",
94
 
             'injected': False,
95
 
             'multi_host': False,
96
 
             'cidr': '103.0.0.0/24',
97
 
             'cidr_v6': '103:1dbb::/64',
98
 
             'gateway_v6': '103:1dbb::1',
99
 
             'netmask_v6': '64',
100
 
             'netmask': '255.255.255.0',
101
 
             'bridge': None,
102
 
             'bridge_interface': None,
103
 
             'gateway': '103.0.0.1',
104
 
             'broadcast': '103.0.0.255',
105
 
             'dns1': '8.8.8.8',
106
 
             'vlan': None,
107
 
             'host': None,
108
 
             'project_id': "fake_project2",
109
 
             'priority': 2}]
110
 
 
111
 
 
112
 
class QuantumConnectionTestCase(test.TestCase):
113
 
 
114
 
    def test_connection(self):
115
 
        fc = fake_client.FakeClient(LOG)
116
 
        qc = quantum_connection.QuantumClientConnection(client=fc)
117
 
        t = "tenant1"
118
 
        net1_name = "net1"
119
 
        net1_uuid = qc.create_network(t, net1_name)
120
 
        self.assertEquals(net1_name, qc.get_network_name(t, net1_uuid))
121
 
        self.assertTrue(qc.network_exists(t, net1_uuid))
122
 
        self.assertFalse(qc.network_exists(t, "fake-uuid"))
123
 
        self.assertFalse(qc.network_exists("fake-tenant", net1_uuid))
124
 
 
125
 
        nets = qc.get_networks(t)['networks']
126
 
        self.assertEquals(len(nets), 1)
127
 
        self.assertEquals(nets[0]['id'], net1_uuid)
128
 
 
129
 
        num_ports = 10
130
 
        for i in range(0, num_ports):
131
 
            qc.create_and_attach_port(t, net1_uuid,
132
 
                                'iface' + str(i), state='ACTIVE')
133
 
 
134
 
        self.assertEquals(len(qc.get_attached_ports(t, net1_uuid)), num_ports)
135
 
 
136
 
        for i in range(0, num_ports):
137
 
            port_uuid = qc.get_port_by_attachment(t, net1_uuid,
138
 
                                'iface' + str(i))
139
 
            self.assertTrue(port_uuid)
140
 
            qc.detach_and_delete_port(t, net1_uuid, port_uuid)
141
 
 
142
 
        self.assertEquals(len(qc.get_attached_ports(t, net1_uuid)), 0)
143
 
 
144
 
        # test port not found
145
 
        qc.create_and_attach_port(t, net1_uuid, 'foo', state='ACTIVE')
146
 
        port_uuid = qc.get_port_by_attachment(t, net1_uuid, 'foo')
147
 
        qc.detach_and_delete_port(t, net1_uuid, port_uuid)
148
 
        self.assertRaises(quantum_client.QuantumNotFoundException,
149
 
                            qc.detach_and_delete_port, t,
150
 
                            net1_uuid, port_uuid)
151
 
 
152
 
        qc.delete_network(t, net1_uuid)
153
 
        self.assertFalse(qc.network_exists(t, net1_uuid))
154
 
        self.assertEquals(len(qc.get_networks(t)['networks']), 0)
155
 
 
156
 
        self.assertRaises(quantum_client.QuantumNotFoundException,
157
 
                            qc.get_network_name, t, net1_uuid)
158
 
 
159
 
 
160
 
# this is a base class to be used by other QuantumManager Test classes
161
 
class QuantumNovaTestCase(test.TestCase):
162
 
 
163
 
    def setUp(self):
164
 
        super(QuantumNovaTestCase, self).setUp()
165
 
 
166
 
        self.flags(quantum_use_dhcp=True)
167
 
        self.flags(l3_lib="nova.network.l3.LinuxNetL3")
168
 
        linuxdrv = "nova.network.linux_net.LinuxOVSInterfaceDriver"
169
 
        self.flags(linuxnet_interface_driver=linuxdrv)
170
 
        fc = fake_client.FakeClient(LOG)
171
 
        qc = quantum_connection.QuantumClientConnection(client=fc)
172
 
 
173
 
        self.net_man = quantum_manager.QuantumManager(
174
 
                ipam_lib="nova.network.quantum.nova_ipam_lib",
175
 
                q_conn=qc)
176
 
 
177
 
        def func(arg1, arg2):
178
 
            pass
179
 
 
180
 
        def func2(arg1, arg2, arg3):
181
 
            pass
182
 
 
183
 
        def func1(arg1):
184
 
            pass
185
 
 
186
 
        self.net_man.driver.update_dhcp_hostfile_with_text = func
187
 
        self.net_man.driver.restart_dhcp = func2
188
 
        self.net_man.driver.kill_dhcp = func1
189
 
 
190
 
        # Tests seem to create some networks by default, which
191
 
        # we don't want.  So we delete them.
192
 
 
193
 
        ctx = context.RequestContext('user1', 'fake_project1').elevated()
194
 
        for n in db.network_get_all(ctx):
195
 
            db.network_delete_safe(ctx, n['id'])
196
 
 
197
 
        # Other unit tests (e.g., test_compute.py) have a nasty
198
 
        # habit of of creating fixed IPs and not cleaning up, which
199
 
        # can confuse these tests, so we remove all existing fixed
200
 
        # ips before starting.
201
 
        session = sql_session.get_session()
202
 
        result = session.query(models.FixedIp).all()
203
 
        with session.begin():
204
 
            for fip_ref in result:
205
 
                session.delete(fip_ref)
206
 
 
207
 
        self.net_man.init_host()
208
 
 
209
 
    def _create_network(self, n):
210
 
        ctx = context.RequestContext('user1', n['project_id'])
211
 
        nwks = self.net_man.create_networks(
212
 
            ctx,
213
 
            label=n['label'], cidr=n['cidr'],
214
 
            multi_host=n['multi_host'],
215
 
            num_networks=1, network_size=256,
216
 
            cidr_v6=n['cidr_v6'],
217
 
            gateway=n['gateway'],
218
 
            gateway_v6=n['gateway_v6'], bridge=None,
219
 
            bridge_interface=None, dns1=n['dns1'],
220
 
            project_id=n['project_id'],
221
 
            priority=n['priority'])
222
 
        n['uuid'] = nwks[0]['uuid']
223
 
 
224
 
 
225
 
class QuantumAllocationTestCase(QuantumNovaTestCase):
226
 
    def test_get_network_in_db(self):
227
 
        context = self.mox.CreateMockAnything()
228
 
        context.elevated().AndReturn('elevated')
229
 
        self.mox.StubOutWithMock(db, 'network_get_by_uuid')
230
 
        self.net_man.context = context
231
 
        db.network_get_by_uuid('elevated', 'quantum_net_id').AndReturn(
232
 
                                                                {'uuid': 1})
233
 
 
234
 
        self.mox.ReplayAll()
235
 
 
236
 
        network = self.net_man.get_network(context, ('quantum_net_id',
237
 
                                                     'net_tenant_id'))
238
 
        self.assertEquals(network['quantum_net_id'], 'quantum_net_id')
239
 
        self.assertEquals(network['uuid'], 1)
240
 
 
241
 
    def test_get_network_not_in_db(self):
242
 
        context = self.mox.CreateMockAnything()
243
 
        context.elevated().AndReturn('elevated')
244
 
        self.mox.StubOutWithMock(db, 'network_get_by_uuid')
245
 
        self.net_man.context = context
246
 
        db.network_get_by_uuid('elevated', 'quantum_net_id').AndReturn(None)
247
 
 
248
 
        self.mox.ReplayAll()
249
 
 
250
 
        network = self.net_man.get_network(context, ('quantum_net_id',
251
 
                                                     'net_tenant_id'))
252
 
        self.assertEquals(network['quantum_net_id'], 'quantum_net_id')
253
 
        self.assertEquals(network['uuid'], 'quantum_net_id')
254
 
 
255
 
 
256
 
class QuantumDeallocationTestCase(QuantumNovaTestCase):
257
 
    def test_deallocate_port(self):
258
 
        quantum = self.mox.CreateMock(
259
 
                                quantum_connection.QuantumClientConnection)
260
 
        quantum.get_port_by_attachment('q_tenant_id', 'net_id',
261
 
                                       'interface_id').AndReturn('port_id')
262
 
        quantum.detach_and_delete_port('q_tenant_id', 'net_id', 'port_id')
263
 
        self.net_man.q_conn = quantum
264
 
 
265
 
        self.mox.ReplayAll()
266
 
 
267
 
        self.net_man.deallocate_port('interface_id', 'net_id', 'q_tenant_id',
268
 
                                     'instance_id')
269
 
 
270
 
    def test_deallocate_port_logs_error(self):
271
 
        quantum = self.mox.CreateMock(
272
 
            quantum_connection.QuantumClientConnection)
273
 
        quantum.get_port_by_attachment('q_tenant_id', 'net_id',
274
 
                            'interface_id').AndRaise(Exception)
275
 
        self.net_man.q_conn = quantum
276
 
 
277
 
        self.mox.StubOutWithMock(quantum_manager.LOG, 'exception')
278
 
        quantum_manager.LOG.exception(mox.Regex(r'port deallocation failed'))
279
 
 
280
 
        self.mox.ReplayAll()
281
 
 
282
 
        self.net_man.deallocate_port('interface_id', 'net_id', 'q_tenant_id',
283
 
                                     'instance_id')
284
 
 
285
 
    def test_deallocate_ip_address(self):
286
 
        ipam = self.mox.CreateMock(melange_ipam_lib.QuantumMelangeIPAMLib)
287
 
        ipam.get_tenant_id_by_net_id('context', 'net_id', {'uuid': 1},
288
 
                                     'project_id').AndReturn('ipam_tenant_id')
289
 
        self.net_man.ipam = ipam
290
 
        self.mox.ReplayAll()
291
 
        self.net_man.deallocate_ip_address('context', 'net_id', 'project_id',
292
 
                {'uuid': 1}, 'instance_id')
293
 
 
294
 
    def test_deallocate_ip_address_2(self):
295
 
        ipam = self.mox.CreateMock(melange_ipam_lib.QuantumMelangeIPAMLib)
296
 
        ipam.get_tenant_id_by_net_id('context', 'net_id', {'uuid': 1},
297
 
                                     'project_id').AndRaise(Exception())
298
 
        self.net_man.ipam = ipam
299
 
 
300
 
        self.mox.StubOutWithMock(quantum_manager.LOG, 'exception')
301
 
        quantum_manager.LOG.exception(mox.Regex(r'ipam deallocation failed'))
302
 
 
303
 
        self.mox.ReplayAll()
304
 
        self.net_man.deallocate_ip_address('context', 'net_id', 'project_id',
305
 
                {'uuid': 1}, 'instance_id')
306
 
 
307
 
 
308
 
class QuantumManagerTestCase(QuantumNovaTestCase):
309
 
    def test_create_and_delete_nets(self):
310
 
        self._create_nets()
311
 
        self._delete_nets()
312
 
 
313
 
    def _create_nets(self):
314
 
        for n in networks:
315
 
            self._create_network(n)
316
 
 
317
 
    def _delete_nets(self):
318
 
        for n in networks:
319
 
            ctx = context.RequestContext('user1', n['project_id'])
320
 
            self.net_man.delete_network(ctx, None, n['uuid'])
321
 
        self.assertRaises(exception.NoNetworksFound,
322
 
                          db.network_get_all, ctx.elevated())
323
 
 
324
 
    def _validate_nw_info(self, nw_info, expected_net_labels):
325
 
 
326
 
        self.assertEquals(len(nw_info), len(expected_net_labels))
327
 
 
328
 
        ctx = context.RequestContext('user1', 'foo').elevated()
329
 
        all_net_map = {}
330
 
        for n in db.network_get_all(ctx):
331
 
            all_net_map[n['label']] = n
332
 
 
333
 
        for i in range(0, len(nw_info)):
334
 
            vif = nw_info[i]
335
 
            net = all_net_map[expected_net_labels[i]]
336
 
 
337
 
            # simple test assumes that each starting prefix is unique
338
 
            expected_v4_cidr_start = net['cidr'].split(".")[0].lower()
339
 
            expected_v6_cidr_start = net['cidr_v6'].split(":")[0].lower()
340
 
 
341
 
            for subnet in vif['network']['subnets']:
342
 
                addr = subnet['ips'][0]['address']
343
 
                if subnet['version'] == 4:
344
 
                    address_start = addr.split(".")[0].lower()
345
 
                    self.assertTrue(expected_v4_cidr_start, address_start)
346
 
                else:
347
 
                    address_start = addr.split(":")[0].lower()
348
 
                    self.assertTrue(expected_v6_cidr_start, address_start)
349
 
 
350
 
        # confirm that there is a DHCP device on corresponding net
351
 
        for l in expected_net_labels:
352
 
            n = all_net_map[l]
353
 
            tenant_id = (n['project_id'] or
354
 
                                FLAGS.quantum_default_tenant_id)
355
 
            ports = self.net_man.q_conn.get_attached_ports(
356
 
                                                    tenant_id, n['uuid'])
357
 
            self.assertEquals(len(ports), 2)  # gw + instance VIF
358
 
 
359
 
            # make sure we aren't allowed to delete network with
360
 
            # active port
361
 
            self.assertRaises(exception.NetworkBusy,
362
 
                              self.net_man.delete_network,
363
 
                              ctx, None, n['uuid'])
364
 
 
365
 
    def _check_vifs(self, expect_num_vifs):
366
 
        ctx = context.RequestContext('user1', "").elevated()
367
 
        self.assertEqual(len(db.virtual_interface_get_all(ctx)),
368
 
                        expect_num_vifs)
369
 
 
370
 
    def _allocate_and_deallocate_instance(self, project_id, requested_networks,
371
 
                                            expected_labels):
372
 
 
373
 
        ctx = context.RequestContext('user1', project_id)
374
 
        self._check_vifs(0)
375
 
 
376
 
        instance_ref = db.instance_create(ctx,
377
 
                                    {"project_id": project_id})
378
 
 
379
 
        nw_info = self.net_man.allocate_for_instance(ctx.elevated(),
380
 
                        instance_id=instance_ref['id'], host="",
381
 
                        rxtx_factor=3,
382
 
                        project_id=project_id,
383
 
                        requested_networks=requested_networks)
384
 
 
385
 
        self._check_vifs(len(nw_info))
386
 
 
387
 
        self._validate_nw_info(nw_info, expected_labels)
388
 
 
389
 
        nw_info = self.net_man.get_instance_nw_info(ctx, instance_ref['id'],
390
 
                                instance_ref['uuid'],
391
 
                                instance_ref['instance_type_id'], "",
392
 
                                project_id=project_id)
393
 
 
394
 
        self._check_vifs(len(nw_info))
395
 
        self._validate_nw_info(nw_info, expected_labels)
396
 
 
397
 
        port_net_pairs = []
398
 
        for vif in nw_info:
399
 
            nid = vif['network']['id']
400
 
            pid = self.net_man.q_conn.get_port_by_attachment(
401
 
                                project_id, nid, vif['id'])
402
 
            if pid is None:
403
 
                pid = self.net_man.q_conn.get_port_by_attachment(
404
 
                                FLAGS.quantum_default_tenant_id,
405
 
                                nid, vif['id'])
406
 
            self.assertTrue(pid is not None)
407
 
            port_net_pairs.append((pid, nid))
408
 
 
409
 
        self.net_man.deallocate_for_instance(ctx,
410
 
                    instance_id=instance_ref['id'],
411
 
                    project_id=project_id)
412
 
 
413
 
        for pid, nid in port_net_pairs:
414
 
            self.assertRaises(quantum_client.QuantumNotFoundException,
415
 
                            self.net_man.q_conn.detach_and_delete_port,
416
 
                            project_id, nid, pid)
417
 
            self.assertRaises(quantum_client.QuantumNotFoundException,
418
 
                            self.net_man.q_conn.detach_and_delete_port,
419
 
                            FLAGS.quantum_default_tenant_id, nid, pid)
420
 
 
421
 
        self._check_vifs(0)
422
 
 
423
 
    def test_allocate_and_deallocate_instance_static(self):
424
 
        self._create_nets()
425
 
        self._allocate_and_deallocate_instance("fake_project1", None,
426
 
                                 ['public', 'project1-net1'])
427
 
        self._delete_nets()
428
 
 
429
 
    def test_allocate_and_deallocate_instance_dynamic(self):
430
 
 
431
 
        self._create_nets()
432
 
        project_id = "fake_project2"
433
 
        ctx = context.RequestContext('user1', project_id)
434
 
        all_valid_networks = self.net_man.ipam.get_project_and_global_net_ids(
435
 
                                                               ctx, project_id)
436
 
        requested_networks = [(n[0], None) for n in all_valid_networks]
437
 
 
438
 
        self.net_man.validate_networks(ctx, requested_networks)
439
 
 
440
 
        label_map = {}
441
 
        for n in db.network_get_all(ctx.elevated()):
442
 
            label_map[n['uuid']] = n['label']
443
 
        expected_labels = [label_map[uid] for uid, _i in requested_networks]
444
 
 
445
 
        self._allocate_and_deallocate_instance(project_id, requested_networks,
446
 
                                              expected_labels)
447
 
        self._delete_nets()
448
 
 
449
 
    def test_validate_bad_network(self):
450
 
        ctx = context.RequestContext('user1', 'fake_project1')
451
 
        self.assertRaises(exception.NetworkNotFound,
452
 
                        self.net_man.validate_networks, ctx, [("", None)])
453
 
 
454
 
    def test_create_net_external_uuid(self):
455
 
        """Tests use case where network can be created directly via
456
 
           Quantum API, then the UUID is passed in via nova-manage"""
457
 
        project_id = "foo_project"
458
 
        ctx = context.RequestContext('user1', project_id)
459
 
        net_id = self.net_man.q_conn.create_network(project_id, 'net1')
460
 
        self.net_man.create_networks(
461
 
            ctx,
462
 
            label='achtungbaby',
463
 
            cidr="9.9.9.0/24",
464
 
            multi_host=False,
465
 
            num_networks=1,
466
 
            network_size=256,
467
 
            cidr_v6=None,
468
 
            gateway="9.9.9.1",
469
 
            gateway_v6=None,
470
 
            bridge=None,
471
 
            bridge_interface=None,
472
 
            dns1="8.8.8.8",
473
 
            project_id=project_id,
474
 
            priority=9,
475
 
            uuid=net_id)
476
 
        net = db.network_get_by_uuid(ctx.elevated(), net_id)
477
 
        self.assertTrue(net is not None)
478
 
        self.assertEquals(net['uuid'], net_id)
479
 
 
480
 
    def test_create_net_external_uuid_and_host_is_set(self):
481
 
        """Make sure network['host'] is set when creating a network via the
482
 
           network manager"""
483
 
        project_id = "foo_project"
484
 
        ctx = context.RequestContext('user1', project_id)
485
 
        net_id = self.net_man.q_conn.create_network(project_id, 'net2')
486
 
        self.net_man.create_networks(
487
 
            ctx, label='achtungbaby2', cidr="9.9.8.0/24", multi_host=False,
488
 
            num_networks=1, network_size=256, cidr_v6=None,
489
 
            gateway="9.9.8.1", gateway_v6=None, bridge=None,
490
 
            bridge_interface=None, dns1="8.8.8.8", project_id=project_id,
491
 
            priority=8, uuid=net_id)
492
 
        net = db.network_get_by_uuid(ctx.elevated(), net_id)
493
 
        self.assertTrue(net is not None)
494
 
        self.assertEquals(net['uuid'], net_id)
495
 
        self.assertTrue(net['host'] != None)
496
 
 
497
 
 
498
 
class QuantumNovaMACGenerationTestCase(QuantumNovaTestCase):
499
 
    def test_local_mac_address_creation(self):
500
 
        self.flags(use_melange_mac_generation=False)
501
 
        fake_mac = "ab:cd:ef:ab:cd:ef"
502
 
        self.stubs.Set(utils, "generate_mac_address",
503
 
                       lambda: fake_mac)
504
 
        project_id = "fake_project1"
505
 
        ctx = context.RequestContext('user1', project_id)
506
 
        self._create_network(networks[0])
507
 
 
508
 
        all_valid_networks = self.net_man.ipam.get_project_and_global_net_ids(
509
 
                                                               ctx, project_id)
510
 
        requested_networks = [(n[0], None) for n in all_valid_networks]
511
 
 
512
 
        instance_ref = db.api.instance_create(ctx,
513
 
                                    {"project_id": project_id})
514
 
        nw_info = self.net_man.allocate_for_instance(ctx,
515
 
                        instance_id=instance_ref['id'], host="",
516
 
                        rxtx_factor=3,
517
 
                        project_id=project_id,
518
 
                        requested_networks=requested_networks)
519
 
        self.assertEqual(nw_info[0]['address'], fake_mac)
520
 
 
521
 
    def test_melange_mac_address_creation(self):
522
 
        self.flags(use_melange_mac_generation=True)
523
 
        fake_mac = "ab:cd:ef:ab:cd:ef"
524
 
        self.stubs.Set(melange_connection.MelangeConnection, "create_vif",
525
 
                       lambda w, x, y, z: fake_mac)
526
 
        project_id = "fake_project1"
527
 
        ctx = context.RequestContext('user1', project_id)
528
 
        self._create_network(networks[0])
529
 
 
530
 
        all_valid_networks = self.net_man.ipam.get_project_and_global_net_ids(
531
 
                                                               ctx, project_id)
532
 
        requested_networks = [(n[0], None) for n in all_valid_networks]
533
 
 
534
 
        instance_ref = db.api.instance_create(ctx,
535
 
                                    {"project_id": project_id})
536
 
        nw_info = self.net_man.allocate_for_instance(ctx,
537
 
                        instance_id=instance_ref['id'], host="",
538
 
                        rxtx_factor=3,
539
 
                        project_id=project_id,
540
 
                        requested_networks=requested_networks)
541
 
        self.assertEqual(nw_info[0]['address'], fake_mac)
542
 
 
543
 
 
544
 
class QuantumNovaPortSecurityTestCase(QuantumNovaTestCase):
545
 
    def test_port_securty(self):
546
 
        self.flags(use_melange_mac_generation=True)
547
 
        self.flags(quantum_use_port_security=True)
548
 
        fake_mac = "ab:cd:ef:ab:cd:ef"
549
 
        self.stubs.Set(melange_connection.MelangeConnection, "create_vif",
550
 
                       lambda w, x, y, z: fake_mac)
551
 
        project_id = "fake_project1"
552
 
        ctx = context.RequestContext('user1', project_id)
553
 
        self._create_network(networks[0])
554
 
 
555
 
        all_valid_networks = self.net_man.ipam.get_project_and_global_net_ids(
556
 
                                                               ctx, project_id)
557
 
        requested_networks = [(n[0], None) for n in all_valid_networks]
558
 
 
559
 
        instance_ref = db.api.instance_create(ctx,
560
 
                                    {"project_id": project_id})
561
 
        oldfunc = self.net_man.q_conn.create_and_attach_port
562
 
 
563
 
        # Make sure we get the appropriate mac set in allowed_address_pairs
564
 
        # if port security is enabled.
565
 
        def _instrumented_create_and_attach_port(tenant_id, net_id,
566
 
                                                 interface_id, **kwargs):
567
 
            self.assertTrue('allowed_address_pairs' in kwargs.keys())
568
 
            pairs = kwargs['allowed_address_pairs']
569
 
            self.assertTrue(pairs[0]['mac_address'] == fake_mac)
570
 
            self.net_man.q_conn.create_and_attach_port = oldfunc
571
 
            return oldfunc(tenant_id, net_id, interface_id, **kwargs)
572
 
        _port_attach = _instrumented_create_and_attach_port
573
 
        self.net_man.q_conn.create_and_attach_port = _port_attach
574
 
        nw_info = self.net_man.allocate_for_instance(ctx,
575
 
                        instance_id=instance_ref['id'], host="",
576
 
                        rxtx_factor=3,
577
 
                        project_id=project_id,
578
 
                        requested_networks=requested_networks)
579
 
        self.assertEqual(nw_info[0]['address'], fake_mac)
580
 
 
581
 
    def test_port_securty_negative(self):
582
 
        self.flags(use_melange_mac_generation=True)
583
 
        self.flags(quantum_use_port_security=False)
584
 
        fake_mac = "ab:cd:ef:ab:cd:ef"
585
 
        self.stubs.Set(melange_connection.MelangeConnection, "create_vif",
586
 
                       lambda w, x, y, z: fake_mac)
587
 
        project_id = "fake_project1"
588
 
        ctx = context.RequestContext('user1', project_id)
589
 
        self._create_network(networks[0])
590
 
 
591
 
        all_valid_networks = self.net_man.ipam.get_project_and_global_net_ids(
592
 
                                                               ctx, project_id)
593
 
        requested_networks = [(n[0], None) for n in all_valid_networks]
594
 
 
595
 
        instance_ref = db.api.instance_create(ctx,
596
 
                                    {"project_id": project_id})
597
 
        oldfunc = self.net_man.q_conn.create_and_attach_port
598
 
 
599
 
        # Make sure no pairs are passed in if port security is turned off
600
 
        def _instrumented_create_and_attach_port(tenant_id, net_id,
601
 
                                                 interface_id, **kwargs):
602
 
            self.assertTrue('allowed_address_pairs' in kwargs.keys())
603
 
            pairs = kwargs['allowed_address_pairs']
604
 
            self.assertTrue(len(pairs) == 0)
605
 
            self.net_man.q_conn.create_and_attach_port = oldfunc
606
 
            return oldfunc(tenant_id, net_id, interface_id, **kwargs)
607
 
        _port_attach = _instrumented_create_and_attach_port
608
 
        self.net_man.q_conn.create_and_attach_port = _port_attach
609
 
        nw_info = self.net_man.allocate_for_instance(ctx,
610
 
                        instance_id=instance_ref['id'], host="",
611
 
                        rxtx_factor=3,
612
 
                        project_id=project_id,
613
 
                        requested_networks=requested_networks)
614
 
        self.assertEqual(nw_info[0]['address'], fake_mac)
615
 
 
616
 
 
617
 
class QuantumMelangeTestCase(test.TestCase):
618
 
    def setUp(self):
619
 
        super(QuantumMelangeTestCase, self).setUp()
620
 
 
621
 
        fc = fake_client.FakeClient(LOG)
622
 
        qc = quantum_connection.QuantumClientConnection(client=fc)
623
 
 
624
 
        self.net_man = quantum_manager.QuantumManager(
625
 
            ipam_lib="nova.network.quantum.nova_ipam_lib",
626
 
            q_conn=qc)
627
 
 
628
 
    def test_get_instance_uuids_by_ip_filter(self):
629
 
        fake_context = context.RequestContext('user', 'project')
630
 
        address = '1.2.3.4'
631
 
        filters = {'ip': address}
632
 
 
633
 
        self.net_man.ipam = self.mox.CreateMockAnything()
634
 
        self.net_man.ipam.get_instance_ids_by_ip_address(fake_context,
635
 
                address).AndReturn(['instance_id'])
636
 
 
637
 
        instance = self.mox.CreateMockAnything()
638
 
        instance.uuid = 'instance_uuid'
639
 
 
640
 
        self.mox.StubOutWithMock(db, 'instance_get')
641
 
        db.instance_get(fake_context, 'instance_id').AndReturn(instance)
642
 
 
643
 
        self.mox.ReplayAll()
644
 
 
645
 
        uuids = self.net_man.get_instance_uuids_by_ip_filter(fake_context,
646
 
                                                             filters)
647
 
        self.assertEquals(uuids, [{'instance_uuid':'instance_uuid'}])