1
# vim: tabstop=4 shiftwidth=4 softtabstop=4
3
# Licensed under the Apache License, Version 2.0 (the "License"); you may
4
# not use this file except in compliance with the License. You may obtain
5
# a copy of the License at
7
# http://www.apache.org/licenses/LICENSE-2.0
9
# Unless required by applicable law or agreed to in writing, software
10
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
11
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
12
# License for the specific language governing permissions and limitations
16
from testtools import skipIf
18
from heat.common import exception
19
from heat.common import template_format
20
from heat.engine import properties
21
from heat.engine import resource
22
from heat.engine import scheduler
23
from heat.engine.resources.quantum import net
24
from heat.engine.resources.quantum import subnet
25
from heat.engine.resources.quantum import router
26
from heat.engine.resources.quantum.quantum import QuantumResource as qr
27
from heat.openstack.common.importutils import try_import
28
from heat.tests.common import HeatTestCase
29
from heat.tests import utils
30
from heat.tests.utils import setup_dummy_db
31
from heat.tests.utils import parse_stack
33
quantumclient = try_import('quantumclient.v2_0.client')
34
qe = try_import('quantumclient.common.exceptions')
36
quantum_template = '''
38
"AWSTemplateFormatVersion" : "2010-09-09",
39
"Description" : "Template to test Quantum resources",
43
"Type": "OS::Quantum::Net",
49
"Type": "OS::Quantum::Net"
51
"admin_down_network": {
52
"Type": "OS::Quantum::Net",
54
"admin_state_up": false
58
"Type": "OS::Quantum::Subnet",
60
"network_id": { "Ref" : "network" },
62
"cidr": "10.0.3.0/24",
63
"allocation_pools": [{"start": "10.0.3.20", "end": "10.0.3.150"}],
64
"dns_nameservers": ["8.8.8.8"]
68
"Type": "OS::Quantum::Port",
70
"device_id": "d6b4d3a5-c700-476f-b609-1493dd9dadc0",
72
"network_id": { "Ref" : "network" },
74
"subnet_id": { "Ref" : "subnet" },
75
"ip_address": "10.0.3.21"
80
"Type": "OS::Quantum::Port",
83
"network_id": { "Ref" : "network" }
87
"Type": "OS::Quantum::Router"
90
"Type": "OS::Quantum::RouterInterface",
92
"router_id": { "Ref" : "router" },
93
"subnet_id": { "Ref" : "subnet" }
97
"Type": "OS::Quantum::RouterGateway",
99
"router_id": { "Ref" : "router" },
100
"network_id": { "Ref" : "network" }
107
quantum_floating_template = '''
109
"AWSTemplateFormatVersion" : "2010-09-09",
110
"Description" : "Template to test Quantum resources",
114
"Type": "OS::Quantum::Port",
116
"network_id": "xyz1234",
118
"subnet_id": "12.12.12.0",
119
"ip_address": "10.0.0.10"
124
"Type": "OS::Quantum::FloatingIP",
126
"floating_network_id": "abcd1234",
129
"floating_ip_assoc": {
130
"Type": "OS::Quantum::FloatingIPAssociation",
132
"floatingip_id": { "Ref" : "floating_ip" },
133
"port_id": { "Ref" : "port_floating" }
137
"Type": "OS::Quantum::Router"
140
"Type": "OS::Quantum::RouterGateway",
142
"router_id": { "Ref" : "router" },
143
"network_id": "abcd1234"
151
class QuantumTest(HeatTestCase):
153
def test_validate_properties(self):
154
vs = {'router:external': True}
155
data = {'admin_state_up': False,
157
p = properties.Properties(net.Net.properties_schema, data)
158
self.assertEqual(None, qr.validate_properties(p))
161
self.assertEqual('shared not allowed in value_specs',
162
qr.validate_properties(p))
166
self.assertEqual('name not allowed in value_specs',
167
qr.validate_properties(p))
170
vs['tenant_id'] = '1234'
171
self.assertEqual('tenant_id not allowed in value_specs',
172
qr.validate_properties(p))
176
self.assertEqual(None, qr.validate_properties(p))
178
def test_prepare_properties(self):
179
data = {'admin_state_up': False,
180
'value_specs': {'router:external': True}}
181
p = properties.Properties(net.Net.properties_schema, data)
182
props = qr.prepare_properties(p, 'resource_name')
183
self.assertEqual({'name': 'resource_name',
184
'router:external': True,
185
'admin_state_up': False}, props)
187
def test_is_built(self):
188
self.assertTrue(qr.is_built({
192
self.assertTrue(qr.is_built({
196
self.assertFalse(qr.is_built({
200
self.assertRaises(exception.Error, qr.is_built, {
202
'status': 'FROBULATING'
206
@skipIf(quantumclient is None, 'quantumclient unavailable')
207
class QuantumNetTest(HeatTestCase):
210
super(QuantumNetTest, self).setUp()
211
self.m.StubOutWithMock(quantumclient.Client, 'create_network')
212
self.m.StubOutWithMock(quantumclient.Client, 'delete_network')
213
self.m.StubOutWithMock(quantumclient.Client, 'show_network')
216
def create_net(self, t, stack, resource_name):
217
rsrc = net.Net('test_net', t['Resources'][resource_name], stack)
218
scheduler.TaskRunner(rsrc.create)()
219
self.assertEqual((rsrc.CREATE, rsrc.COMPLETE), rsrc.state)
223
quantumclient.Client.create_network({
224
'network': {'name': u'the_network', 'admin_state_up': True}
225
}).AndReturn({"network": {
229
"admin_state_up": False,
231
"tenant_id": "c1210485b2424d48804aad5d39c61b8f",
232
"id": "fc68ea2c-b60b-4b4f-bd82-94ec81110766"
235
quantumclient.Client.show_network(
236
'fc68ea2c-b60b-4b4f-bd82-94ec81110766'
237
).AndReturn({"network": {
241
"admin_state_up": False,
243
"tenant_id": "c1210485b2424d48804aad5d39c61b8f",
244
"id": "fc68ea2c-b60b-4b4f-bd82-94ec81110766"
247
quantumclient.Client.show_network(
248
'fc68ea2c-b60b-4b4f-bd82-94ec81110766'
249
).AndReturn({"network": {
253
"admin_state_up": False,
255
"tenant_id": "c1210485b2424d48804aad5d39c61b8f",
256
"id": "fc68ea2c-b60b-4b4f-bd82-94ec81110766"
259
quantumclient.Client.show_network(
260
'fc68ea2c-b60b-4b4f-bd82-94ec81110766'
261
).AndRaise(qe.QuantumClientException(status_code=404))
263
quantumclient.Client.show_network(
264
'fc68ea2c-b60b-4b4f-bd82-94ec81110766'
265
).AndReturn({"network": {
269
"admin_state_up": False,
271
"tenant_id": "c1210485b2424d48804aad5d39c61b8f",
272
"id": "fc68ea2c-b60b-4b4f-bd82-94ec81110766"
275
quantumclient.Client.show_network(
276
'fc68ea2c-b60b-4b4f-bd82-94ec81110766'
277
).AndReturn({"network": {
281
"admin_state_up": False,
283
"tenant_id": "c1210485b2424d48804aad5d39c61b8f",
284
"id": "fc68ea2c-b60b-4b4f-bd82-94ec81110766"
287
quantumclient.Client.delete_network(
288
'fc68ea2c-b60b-4b4f-bd82-94ec81110766'
291
quantumclient.Client.show_network(
292
'fc68ea2c-b60b-4b4f-bd82-94ec81110766'
293
).AndRaise(qe.QuantumClientException(status_code=404))
295
quantumclient.Client.delete_network(
296
'fc68ea2c-b60b-4b4f-bd82-94ec81110766'
297
).AndRaise(qe.QuantumClientException(status_code=404))
300
t = template_format.parse(quantum_template)
301
stack = parse_stack(t)
302
rsrc = self.create_net(t, stack, 'network')
304
# assert the implicit dependency between the gateway and the interface
305
deps = stack.dependencies[stack['router_interface']]
306
self.assertIn(stack['gateway'], deps)
308
# assert the implicit dependency between the gateway and the subnet
309
deps = stack.dependencies[stack['subnet']]
310
self.assertIn(stack['gateway'], deps)
314
ref_id = rsrc.FnGetRefId()
315
self.assertEqual('fc68ea2c-b60b-4b4f-bd82-94ec81110766', ref_id)
317
self.assertEqual(None, rsrc.FnGetAtt('status'))
318
self.assertEqual('ACTIVE', rsrc.FnGetAtt('status'))
321
raise Exception('Expected InvalidTemplateAttribute')
322
except exception.InvalidTemplateAttribute:
325
self.assertEqual('fc68ea2c-b60b-4b4f-bd82-94ec81110766',
328
self.assertRaises(resource.UpdateReplace,
329
rsrc.handle_update, {}, {}, {})
331
scheduler.TaskRunner(rsrc.delete)()
332
rsrc.state_set(rsrc.CREATE, rsrc.COMPLETE, 'to delete again')
333
scheduler.TaskRunner(rsrc.delete)()
337
@skipIf(quantumclient is None, 'quantumclient unavailable')
338
class QuantumSubnetTest(HeatTestCase):
341
super(QuantumSubnetTest, self).setUp()
342
self.m.StubOutWithMock(quantumclient.Client, 'create_subnet')
343
self.m.StubOutWithMock(quantumclient.Client, 'delete_subnet')
344
self.m.StubOutWithMock(quantumclient.Client, 'show_subnet')
347
def create_subnet(self, t, stack, resource_name):
348
rsrc = subnet.Subnet('test_subnet', t['Resources'][resource_name],
350
scheduler.TaskRunner(rsrc.create)()
351
self.assertEqual((rsrc.CREATE, rsrc.COMPLETE), rsrc.state)
354
def test_subnet(self):
356
quantumclient.Client.create_subnet({
358
'name': utils.PhysName('test_stack', 'test_subnet'),
359
'network_id': u'None',
360
'dns_nameservers': [u'8.8.8.8'],
361
'allocation_pools': [
362
{'start': u'10.0.3.20', 'end': u'10.0.3.150'}],
364
'cidr': u'10.0.3.0/24'
368
"allocation_pools": [
369
{"start": "10.0.3.20", "end": "10.0.3.150"}],
370
"cidr": "10.0.3.0/24",
371
"dns_nameservers": ["8.8.8.8"],
373
"gateway_ip": "10.0.3.1",
374
"id": "91e47a57-7508-46fe-afc9-fc454e8580e1",
377
"network_id": "fc68ea2c-b60b-4b4f-bd82-94ec81110766",
378
"tenant_id": "c1210485b2424d48804aad5d39c61b8f"
381
quantumclient.Client.show_subnet(
382
'91e47a57-7508-46fe-afc9-fc454e8580e1').AndRaise(
383
qe.QuantumClientException(status_code=404))
387
"network_id": "fc68ea2c-b60b-4b4f-bd82-94ec81110766",
388
"tenant_id": "c1210485b2424d48804aad5d39c61b8f",
389
"allocation_pools": [
390
{"start": "10.0.3.20", "end": "10.0.3.150"}],
391
"gateway_ip": "10.0.3.1",
393
"cidr": "10.0.3.0/24",
394
"dns_nameservers": ["8.8.8.8"],
395
"id": "91e47a57-7508-46fe-afc9-fc454e8580e1",
399
quantumclient.Client.show_subnet(
400
'91e47a57-7508-46fe-afc9-fc454e8580e1').AndReturn(sn)
401
quantumclient.Client.show_subnet(
402
'91e47a57-7508-46fe-afc9-fc454e8580e1').AndReturn(sn)
403
quantumclient.Client.show_subnet(
404
'91e47a57-7508-46fe-afc9-fc454e8580e1').AndReturn(sn)
406
quantumclient.Client.delete_subnet(
407
'91e47a57-7508-46fe-afc9-fc454e8580e1'
410
quantumclient.Client.show_subnet(
411
'91e47a57-7508-46fe-afc9-fc454e8580e1'
412
).AndRaise(qe.QuantumClientException(status_code=404))
414
quantumclient.Client.delete_subnet(
415
'91e47a57-7508-46fe-afc9-fc454e8580e1'
416
).AndRaise(qe.QuantumClientException(status_code=404))
419
t = template_format.parse(quantum_template)
420
stack = parse_stack(t)
421
rsrc = self.create_subnet(t, stack, 'subnet')
425
ref_id = rsrc.FnGetRefId()
426
self.assertEqual('91e47a57-7508-46fe-afc9-fc454e8580e1', ref_id)
427
self.assertEqual(None,
428
rsrc.FnGetAtt('network_id'))
429
self.assertEqual('fc68ea2c-b60b-4b4f-bd82-94ec81110766',
430
rsrc.FnGetAtt('network_id'))
431
self.assertEqual('8.8.8.8', rsrc.FnGetAtt('dns_nameservers')[0])
432
self.assertEqual('91e47a57-7508-46fe-afc9-fc454e8580e1',
435
# assert the dependency (implicit or explicit) between the ports
437
self.assertIn(stack['port'], stack.dependencies[stack['subnet']])
438
self.assertIn(stack['port2'], stack.dependencies[stack['subnet']])
440
self.assertRaises(resource.UpdateReplace,
441
rsrc.handle_update, {}, {}, {})
443
self.assertEqual(scheduler.TaskRunner(rsrc.delete)(), None)
444
rsrc.state_set(rsrc.CREATE, rsrc.COMPLETE, 'to delete again')
445
self.assertEqual(scheduler.TaskRunner(rsrc.delete)(), None)
448
def test_subnet_disable_dhcp(self):
450
quantumclient.Client.create_subnet({
452
'name': utils.PhysName('test_stack', 'test_subnet'),
453
'network_id': u'None',
454
'dns_nameservers': [u'8.8.8.8'],
455
'allocation_pools': [
456
{'start': u'10.0.3.20', 'end': u'10.0.3.150'}],
458
'enable_dhcp': False,
459
'cidr': u'10.0.3.0/24'
463
"allocation_pools": [
464
{"start": "10.0.3.20", "end": "10.0.3.150"}],
465
"cidr": "10.0.3.0/24",
466
"dns_nameservers": ["8.8.8.8"],
467
"enable_dhcp": False,
468
"gateway_ip": "10.0.3.1",
469
"id": "91e47a57-7508-46fe-afc9-fc454e8580e1",
472
"network_id": "fc68ea2c-b60b-4b4f-bd82-94ec81110766",
473
"tenant_id": "c1210485b2424d48804aad5d39c61b8f"
477
quantumclient.Client.show_subnet(
478
'91e47a57-7508-46fe-afc9-fc454e8580e1').AndReturn({
481
"network_id": "fc68ea2c-b60b-4b4f-bd82-94ec81110766",
482
"tenant_id": "c1210485b2424d48804aad5d39c61b8f",
483
"allocation_pools": [
484
{"start": "10.0.3.20", "end": "10.0.3.150"}],
485
"gateway_ip": "10.0.3.1",
487
"cidr": "10.0.3.0/24",
488
"dns_nameservers": ["8.8.8.8"],
489
"id": "91e47a57-7508-46fe-afc9-fc454e8580e1",
490
"enable_dhcp": False,
494
quantumclient.Client.delete_subnet(
495
'91e47a57-7508-46fe-afc9-fc454e8580e1'
498
quantumclient.Client.show_subnet(
499
'91e47a57-7508-46fe-afc9-fc454e8580e1'
500
).AndRaise(qe.QuantumClientException(status_code=404))
503
t = template_format.parse(quantum_template)
504
t['Resources']['subnet']['Properties']['enable_dhcp'] = 'False'
505
stack = parse_stack(t)
506
rsrc = self.create_subnet(t, stack, 'subnet')
510
ref_id = rsrc.FnGetRefId()
511
self.assertEqual('91e47a57-7508-46fe-afc9-fc454e8580e1', ref_id)
512
self.assertEqual(False, rsrc.FnGetAtt('enable_dhcp'))
513
self.assertEqual(rsrc.delete(), None)
517
@skipIf(quantumclient is None, 'quantumclient unavailable')
518
class QuantumRouterTest(HeatTestCase):
520
super(QuantumRouterTest, self).setUp()
521
self.m.StubOutWithMock(quantumclient.Client, 'create_router')
522
self.m.StubOutWithMock(quantumclient.Client, 'delete_router')
523
self.m.StubOutWithMock(quantumclient.Client, 'show_router')
524
self.m.StubOutWithMock(quantumclient.Client, 'add_interface_router')
525
self.m.StubOutWithMock(quantumclient.Client, 'remove_interface_router')
526
self.m.StubOutWithMock(quantumclient.Client, 'add_gateway_router')
527
self.m.StubOutWithMock(quantumclient.Client, 'remove_gateway_router')
530
def create_router(self, t, stack, resource_name):
531
rsrc = router.Router('router', t['Resources'][resource_name], stack)
532
scheduler.TaskRunner(rsrc.create)()
533
self.assertEqual((rsrc.CREATE, rsrc.COMPLETE), rsrc.state)
536
def create_router_interface(self, t, stack, resource_name, properties={}):
537
t['Resources'][resource_name]['Properties'] = properties
538
rsrc = router.RouterInterface(
540
t['Resources'][resource_name],
542
scheduler.TaskRunner(rsrc.create)()
543
self.assertEqual((rsrc.CREATE, rsrc.COMPLETE), rsrc.state)
546
def create_gateway_router(self, t, stack, resource_name, properties={}):
547
t['Resources'][resource_name]['Properties'] = properties
548
rsrc = router.RouterGateway(
550
t['Resources'][resource_name],
552
scheduler.TaskRunner(rsrc.create)()
553
self.assertEqual((rsrc.CREATE, rsrc.COMPLETE), rsrc.state)
556
def test_router(self):
557
quantumclient.Client.create_router({
559
'name': utils.PhysName('test_stack', 'router'),
560
'admin_state_up': True,
565
"external_gateway_info": None,
566
"name": utils.PhysName('test_stack', 'router'),
567
"admin_state_up": True,
568
"tenant_id": "3e21026f2dc94372b105808c0e721661",
569
"id": "3e46229d-8fce-4733-819a-b5fe630550f8"
572
quantumclient.Client.show_router(
573
'3e46229d-8fce-4733-819a-b5fe630550f8').AndReturn({
576
"external_gateway_info": None,
577
"name": utils.PhysName('test_stack', 'router'),
578
"admin_state_up": True,
579
"tenant_id": "3e21026f2dc94372b105808c0e721661",
581
"id": "3e46229d-8fce-4733-819a-b5fe630550f8"
584
quantumclient.Client.show_router(
585
'3e46229d-8fce-4733-819a-b5fe630550f8').AndReturn({
588
"external_gateway_info": None,
589
"name": utils.PhysName('test_stack', 'router'),
590
"admin_state_up": True,
591
"tenant_id": "3e21026f2dc94372b105808c0e721661",
593
"id": "3e46229d-8fce-4733-819a-b5fe630550f8"
597
quantumclient.Client.show_router(
598
'3e46229d-8fce-4733-819a-b5fe630550f8').AndRaise(
599
qe.QuantumClientException(status_code=404))
600
quantumclient.Client.show_router(
601
'3e46229d-8fce-4733-819a-b5fe630550f8').AndReturn({
604
"external_gateway_info": None,
605
"name": utils.PhysName('test_stack', 'router'),
606
"admin_state_up": True,
607
"tenant_id": "3e21026f2dc94372b105808c0e721661",
609
"id": "3e46229d-8fce-4733-819a-b5fe630550f8"
612
quantumclient.Client.show_router(
613
'3e46229d-8fce-4733-819a-b5fe630550f8').AndReturn({
616
"external_gateway_info": None,
617
"name": utils.PhysName('test_stack', 'router'),
618
"admin_state_up": True,
619
"tenant_id": "3e21026f2dc94372b105808c0e721661",
621
"id": "3e46229d-8fce-4733-819a-b5fe630550f8"
625
quantumclient.Client.delete_router(
626
'3e46229d-8fce-4733-819a-b5fe630550f8'
629
quantumclient.Client.show_router(
630
'3e46229d-8fce-4733-819a-b5fe630550f8'
631
).AndRaise(qe.QuantumClientException(status_code=404))
633
quantumclient.Client.delete_router(
634
'3e46229d-8fce-4733-819a-b5fe630550f8'
635
).AndRaise(qe.QuantumClientException(status_code=404))
638
t = template_format.parse(quantum_template)
639
stack = parse_stack(t)
640
rsrc = self.create_router(t, stack, 'router')
644
ref_id = rsrc.FnGetRefId()
645
self.assertEqual('3e46229d-8fce-4733-819a-b5fe630550f8', ref_id)
646
self.assertEqual(None,
647
rsrc.FnGetAtt('tenant_id'))
648
self.assertEqual('3e21026f2dc94372b105808c0e721661',
649
rsrc.FnGetAtt('tenant_id'))
650
self.assertEqual('3e46229d-8fce-4733-819a-b5fe630550f8',
653
self.assertRaises(resource.UpdateReplace,
654
rsrc.handle_update, {}, {}, {})
656
self.assertEqual(scheduler.TaskRunner(rsrc.delete)(), None)
657
rsrc.state_set(rsrc.CREATE, rsrc.COMPLETE, 'to delete again')
658
self.assertEqual(scheduler.TaskRunner(rsrc.delete)(), None)
661
def test_router_interface(self):
662
quantumclient.Client.add_interface_router(
663
'3e46229d-8fce-4733-819a-b5fe630550f8',
664
{'subnet_id': '91e47a57-7508-46fe-afc9-fc454e8580e1'}
666
quantumclient.Client.remove_interface_router(
667
'3e46229d-8fce-4733-819a-b5fe630550f8',
668
{'subnet_id': '91e47a57-7508-46fe-afc9-fc454e8580e1'}
670
quantumclient.Client.remove_interface_router(
671
'3e46229d-8fce-4733-819a-b5fe630550f8',
672
{'subnet_id': '91e47a57-7508-46fe-afc9-fc454e8580e1'}
673
).AndRaise(qe.QuantumClientException(status_code=404))
675
t = template_format.parse(quantum_template)
676
stack = parse_stack(t)
678
rsrc = self.create_router_interface(
679
t, stack, 'router_interface', properties={
680
'router_id': '3e46229d-8fce-4733-819a-b5fe630550f8',
681
'subnet_id': '91e47a57-7508-46fe-afc9-fc454e8580e1'
684
self.assertEqual(rsrc.delete(), None)
685
rsrc.state_set(rsrc.CREATE, rsrc.COMPLETE, 'to delete again')
686
self.assertEqual(rsrc.delete(), None)
689
def test_gateway_router(self):
690
quantumclient.Client.add_gateway_router(
691
'3e46229d-8fce-4733-819a-b5fe630550f8',
692
{'network_id': 'fc68ea2c-b60b-4b4f-bd82-94ec81110766'}
694
quantumclient.Client.remove_gateway_router(
695
'3e46229d-8fce-4733-819a-b5fe630550f8'
697
quantumclient.Client.remove_gateway_router(
698
'3e46229d-8fce-4733-819a-b5fe630550f8'
699
).AndRaise(qe.QuantumClientException(status_code=404))
701
t = template_format.parse(quantum_template)
702
stack = parse_stack(t)
704
rsrc = self.create_gateway_router(
705
t, stack, 'gateway', properties={
706
'router_id': '3e46229d-8fce-4733-819a-b5fe630550f8',
707
'network_id': 'fc68ea2c-b60b-4b4f-bd82-94ec81110766'
710
self.assertEqual(rsrc.delete(), None)
711
rsrc.state_set(rsrc.CREATE, rsrc.COMPLETE, 'to delete again')
712
self.assertEqual(rsrc.delete(), None)
716
@skipIf(quantumclient is None, 'quantumclient unavailable')
717
class QuantumFloatingIPTest(HeatTestCase):
718
@skipIf(net.clients.quantumclient is None, "Missing Quantum Client")
720
super(QuantumFloatingIPTest, self).setUp()
721
self.m.StubOutWithMock(quantumclient.Client, 'create_floatingip')
722
self.m.StubOutWithMock(quantumclient.Client, 'delete_floatingip')
723
self.m.StubOutWithMock(quantumclient.Client, 'show_floatingip')
724
self.m.StubOutWithMock(quantumclient.Client, 'update_floatingip')
725
self.m.StubOutWithMock(quantumclient.Client, 'create_port')
726
self.m.StubOutWithMock(quantumclient.Client, 'delete_port')
727
self.m.StubOutWithMock(quantumclient.Client, 'show_port')
730
def test_floating_ip(self):
732
quantumclient.Client.create_floatingip({
733
'floatingip': {'floating_network_id': u'abcd1234'}
734
}).AndReturn({'floatingip': {
736
"id": "fc68ea2c-b60b-4b4f-bd82-94ec81110766"
739
quantumclient.Client.show_floatingip(
740
'fc68ea2c-b60b-4b4f-bd82-94ec81110766'
741
).AndRaise(qe.QuantumClientException(status_code=404))
742
quantumclient.Client.show_floatingip(
743
'fc68ea2c-b60b-4b4f-bd82-94ec81110766'
744
).MultipleTimes().AndReturn({'floatingip': {
746
"id": "fc68ea2c-b60b-4b4f-bd82-94ec81110766"
749
quantumclient.Client.delete_floatingip(
750
'fc68ea2c-b60b-4b4f-bd82-94ec81110766').AndReturn(None)
751
quantumclient.Client.delete_floatingip(
752
'fc68ea2c-b60b-4b4f-bd82-94ec81110766').AndRaise(
753
qe.QuantumClientException(status_code=404))
756
t = template_format.parse(quantum_floating_template)
757
stack = parse_stack(t)
759
# assert the implicit dependency between the floating_ip
761
deps = stack.dependencies[stack['gateway']]
762
self.assertIn(stack['floating_ip'], deps)
764
fip = stack['floating_ip']
765
scheduler.TaskRunner(fip.create)()
766
self.assertEqual((fip.CREATE, fip.COMPLETE), fip.state)
769
fip_id = fip.FnGetRefId()
770
self.assertEqual('fc68ea2c-b60b-4b4f-bd82-94ec81110766', fip_id)
772
self.assertEqual(None, fip.FnGetAtt('status'))
773
self.assertEqual('ACTIVE', fip.FnGetAtt('status'))
776
raise Exception('Expected InvalidTemplateAttribute')
777
except exception.InvalidTemplateAttribute:
780
self.assertEqual('fc68ea2c-b60b-4b4f-bd82-94ec81110766',
782
self.assertRaises(resource.UpdateReplace,
783
fip.handle_update, {}, {}, {})
784
self.assertEqual(fip.delete(), None)
785
fip.state_set(fip.CREATE, fip.COMPLETE, 'to delete again')
786
self.assertEqual(fip.delete(), None)
792
quantumclient.Client.create_port({'port': {
793
'network_id': u'xyz1234',
795
{'subnet_id': u'12.12.12.0', 'ip_address': u'10.0.0.10'}
797
'name': utils.PhysName('test_stack', 'port_floating'),
798
'admin_state_up': True}}
799
).AndReturn({'port': {
801
"id": "fc68ea2c-b60b-4b4f-bd82-94ec81110766"
803
quantumclient.Client.show_port(
804
'fc68ea2c-b60b-4b4f-bd82-94ec81110766'
805
).AndReturn({'port': {
807
"id": "fc68ea2c-b60b-4b4f-bd82-94ec81110766"
809
quantumclient.Client.show_port(
810
'fc68ea2c-b60b-4b4f-bd82-94ec81110766'
811
).AndReturn({'port': {
813
"id": "fc68ea2c-b60b-4b4f-bd82-94ec81110766"
815
quantumclient.Client.show_port(
816
'fc68ea2c-b60b-4b4f-bd82-94ec81110766'
817
).AndRaise(qe.QuantumClientException(status_code=404))
818
quantumclient.Client.show_port(
819
'fc68ea2c-b60b-4b4f-bd82-94ec81110766'
820
).MultipleTimes().AndReturn({'port': {
822
"id": "fc68ea2c-b60b-4b4f-bd82-94ec81110766"
827
t = template_format.parse(quantum_floating_template)
828
stack = parse_stack(t)
830
p = stack['port_floating']
831
scheduler.TaskRunner(p.create)()
832
self.assertEqual((p.CREATE, p.COMPLETE), p.state)
835
port_id = p.FnGetRefId()
836
self.assertEqual('fc68ea2c-b60b-4b4f-bd82-94ec81110766', port_id)
838
self.assertEqual(None, p.FnGetAtt('status'))
839
self.assertEqual('ACTIVE', p.FnGetAtt('status'))
842
raise Exception('Expected InvalidTemplateAttribute')
843
except exception.InvalidTemplateAttribute:
846
self.assertEqual('fc68ea2c-b60b-4b4f-bd82-94ec81110766',
849
self.assertRaises(resource.UpdateReplace,
850
p.handle_update, {}, {}, {})
854
def test_floatip_port(self):
856
quantumclient.Client.create_floatingip({
857
'floatingip': {'floating_network_id': u'abcd1234'}
858
}).AndReturn({'floatingip': {
860
"id": "fc68ea2c-b60b-4b4f-bd82-94ec81110766"
863
quantumclient.Client.create_port({'port': {
864
'network_id': u'xyz1234',
866
{'subnet_id': u'12.12.12.0', 'ip_address': u'10.0.0.10'}
868
'name': utils.PhysName('test_stack', 'port_floating'),
869
'admin_state_up': True}}
870
).AndReturn({'port': {
872
"id": "fc68ea2c-b60b-4b4f-bd82-94ec81110766"
874
quantumclient.Client.show_port(
875
'fc68ea2c-b60b-4b4f-bd82-94ec81110766'
876
).AndReturn({'port': {
878
"id": "fc68ea2c-b60b-4b4f-bd82-94ec81110766"
880
quantumclient.Client.update_floatingip(
881
'fc68ea2c-b60b-4b4f-bd82-94ec81110766',
884
'port_id': u'fc68ea2c-b60b-4b4f-bd82-94ec81110766'}}
885
).AndReturn({'floatingip': {
887
"id": "fc68ea2c-b60b-4b4f-bd82-94ec81110766"
890
quantumclient.Client.update_floatingip(
891
'fc68ea2c-b60b-4b4f-bd82-94ec81110766',
896
quantumclient.Client.delete_port(
897
'fc68ea2c-b60b-4b4f-bd82-94ec81110766'
900
quantumclient.Client.show_port(
901
'fc68ea2c-b60b-4b4f-bd82-94ec81110766'
902
).AndRaise(qe.QuantumClientException(status_code=404))
904
quantumclient.Client.delete_floatingip(
905
'fc68ea2c-b60b-4b4f-bd82-94ec81110766'
908
quantumclient.Client.update_floatingip(
909
'fc68ea2c-b60b-4b4f-bd82-94ec81110766',
912
}}).AndRaise(qe.QuantumClientException(status_code=404))
914
quantumclient.Client.delete_port(
915
'fc68ea2c-b60b-4b4f-bd82-94ec81110766'
916
).AndRaise(qe.QuantumClientException(status_code=404))
918
quantumclient.Client.delete_floatingip(
919
'fc68ea2c-b60b-4b4f-bd82-94ec81110766'
920
).AndRaise(qe.QuantumClientException(status_code=404))
924
t = template_format.parse(quantum_floating_template)
925
stack = parse_stack(t)
927
fip = stack['floating_ip']
928
scheduler.TaskRunner(fip.create)()
929
self.assertEqual((fip.CREATE, fip.COMPLETE), fip.state)
931
p = stack['port_floating']
932
scheduler.TaskRunner(p.create)()
933
self.assertEqual((p.CREATE, p.COMPLETE), p.state)
935
fipa = stack['floating_ip_assoc']
936
scheduler.TaskRunner(fipa.create)()
937
self.assertEqual((fipa.CREATE, fipa.COMPLETE), fipa.state)
941
fipa_id = fipa.FnGetRefId()
942
fip_id = fip.FnGetRefId()
943
port_id = p.FnGetRefId()
944
self.assertEqual('%s:%s' % (fip_id, port_id), fipa_id)
945
self.assertRaises(resource.UpdateReplace,
946
fipa.handle_update, {}, {}, {})
948
self.assertEqual(fipa.delete(), None)
949
self.assertEqual(scheduler.TaskRunner(p.delete)(), None)
950
self.assertEqual(fip.delete(), None)
952
fipa.state_set(fipa.CREATE, fipa.COMPLETE, 'to delete again')
953
fip.state_set(fip.CREATE, fip.COMPLETE, 'to delete again')
954
p.state_set(p.CREATE, p.COMPLETE, 'to delete again')
956
self.assertEqual(fipa.delete(), None)
957
self.assertEqual(scheduler.TaskRunner(p.delete)(), None)
958
self.assertEqual(fip.delete(), None)