1
Description: Rename quantumclient to neutronclient
2
Author: Chuck Short <zulcss@ubuntu.com>
4
diff -Naurp heat-2013.2.b2.orig/doc/docbkx/heat-cli-guide/src/heat_cli_howto.xml heat-2013.2.b2/doc/docbkx/heat-cli-guide/src/heat_cli_howto.xml
5
--- heat-2013.2.b2.orig/doc/docbkx/heat-cli-guide/src/heat_cli_howto.xml 2013-08-07 22:22:07.371156844 +0000
6
+++ heat-2013.2.b2/doc/docbkx/heat-cli-guide/src/heat_cli_howto.xml 2013-08-07 22:24:21.095156844 +0000
8
xmlns:svg="http://www.w3.org/2000/svg"
9
xmlns:html="http://www.w3.org/1999/xhtml"
11
- xml:id="quantum-cli-reference">
12
+ xml:id="neutron-cli-reference">
13
<?dbhtml stop-chunking?>
14
<title>OpenStack Heat CLI Guide</title>
15
<para>This section describes heat commands</para>
16
diff -Naurp heat-2013.2.b2.orig/heat/engine/clients.py heat-2013.2.b2/heat/engine/clients.py
17
--- heat-2013.2.b2.orig/heat/engine/clients.py 2013-08-07 22:22:07.379156844 +0000
18
+++ heat-2013.2.b2/heat/engine/clients.py 2013-08-07 22:30:05.203156844 +0000
19
@@ -29,10 +29,10 @@ except ImportError:
21
logger.info('swiftclient not available')
23
- from quantumclient.v2_0 import client as quantumclient
24
+ from neutronclient.v2_0 import client as neutronclient
26
- quantumclient = None
27
- logger.info('quantumclient not available')
28
+ neutronclient = None
29
+ logger.info('neutronclient not available')
31
from cinderclient import client as cinderclient
33
@@ -58,7 +58,7 @@ class OpenStackClients(object):
37
- self._quantum = None
38
+ self._neutron = None
42
@@ -130,12 +130,12 @@ class OpenStackClients(object):
43
self._swift = swiftclient.Connection(**args)
47
- if quantumclient is None:
49
+ if neutronclient is None:
52
- logger.debug('using existing _quantum')
53
- return self._quantum
55
+ logger.debug('using existing _neutron')
56
+ return self._neutron
60
@@ -154,11 +154,11 @@ class OpenStackClients(object):
61
logger.error("Quantum connection failed, "
62
"no password or auth_token!")
64
- logger.debug('quantum args %s', args)
65
+ logger.debug('neutron args %s', args)
67
- self._quantum = quantumclient.Client(**args)
68
+ self._neutron = neutronclient.Client(**args)
70
- return self._quantum
71
+ return self._neutron
74
if cinderclient is None:
75
diff -Naurp heat-2013.2.b2.orig/heat/engine/resource.py heat-2013.2.b2/heat/engine/resource.py
76
--- heat-2013.2.b2.orig/heat/engine/resource.py 2013-08-07 22:22:07.379156844 +0000
77
+++ heat-2013.2.b2/heat/engine/resource.py 2013-08-07 22:24:21.095156844 +0000
78
@@ -321,8 +321,8 @@ class Resource(object):
80
return self.stack.clients.swift()
83
- return self.stack.clients.quantum()
85
+ return self.stack.clients.neutron()
88
return self.stack.clients.cinder()
89
diff -Naurp heat-2013.2.b2.orig/heat/engine/resources/instance.py heat-2013.2.b2/heat/engine/resources/instance.py
90
--- heat-2013.2.b2.orig/heat/engine/resources/instance.py 2013-08-07 22:22:07.379156844 +0000
91
+++ heat-2013.2.b2/heat/engine/resources/instance.py 2013-08-07 22:24:21.095156844 +0000
92
@@ -258,9 +258,9 @@ class Instance(resource.Resource):
94
# if SubnetId property in Instance, ensure subnet exists
96
- quantumclient = self.quantum()
97
+ neutronclient = self.neutron()
98
network_id = NetworkInterface.network_id_from_subnet_id(
99
- quantumclient, subnet_id)
100
+ neutronclient, subnet_id)
101
# if subnet verified, create a port to use this subnet
102
# if port is not created explicitly, nova will choose
103
# the first subnet in the given network.
104
@@ -271,7 +271,7 @@ class Instance(resource.Resource):
105
'network_id': network_id,
106
'fixed_ips': [fixed_ip]
108
- port = quantumclient.create_port({'port': props})['port']
109
+ port = neutronclient.create_port({'port': props})['port']
110
nics = [{'port-id': port['id']}]
113
diff -Naurp heat-2013.2.b2.orig/heat/engine/resources/internet_gateway.py heat-2013.2.b2/heat/engine/resources/internet_gateway.py
114
--- heat-2013.2.b2.orig/heat/engine/resources/internet_gateway.py 2013-08-07 22:22:07.379156844 +0000
115
+++ heat-2013.2.b2/heat/engine/resources/internet_gateway.py 2013-08-07 22:24:21.095156844 +0000
116
@@ -83,26 +83,26 @@ class VPCGatewayAttachment(resource.Reso
117
deps += (self, route_table)
119
def handle_create(self):
120
- client = self.quantum()
121
+ client = self.neutron()
122
external_network_id = InternetGateway.get_external_network_id(client)
123
for router in self._vpc_route_tables():
124
client.add_gateway_router(router.resource_id, {
125
'network_id': external_network_id})
127
def handle_delete(self):
128
- from quantumclient.common.exceptions import QuantumClientException
129
+ from neutronclient.common.exceptions import NeutronClientException
131
- client = self.quantum()
132
+ client = self.neutron()
133
for router in self._vpc_route_tables():
135
client.remove_gateway_router(router.resource_id)
136
- except QuantumClientException as ex:
137
+ except NeutronClientException as ex:
138
if ex.status_code != 404:
142
def resource_mapping():
143
- if clients.quantumclient is None:
144
+ if clients.neutronclient is None:
148
diff -Naurp heat-2013.2.b2.orig/heat/engine/resources/network_interface.py heat-2013.2.b2/heat/engine/resources/network_interface.py
149
--- heat-2013.2.b2.orig/heat/engine/resources/network_interface.py 2013-08-07 22:22:07.379156844 +0000
150
+++ heat-2013.2.b2/heat/engine/resources/network_interface.py 2013-08-07 22:24:21.095156844 +0000
151
@@ -44,12 +44,12 @@ class NetworkInterface(resource.Resource
155
- def network_id_from_subnet_id(quantumclient, subnet_id):
156
- subnet_info = quantumclient.show_subnet(subnet_id)
157
+ def network_id_from_subnet_id(neutronclient, subnet_id):
158
+ subnet_info = neutronclient.show_subnet(subnet_id)
159
return subnet_info['subnet']['network_id']
161
def handle_create(self):
162
- client = self.quantum()
163
+ client = self.neutron()
165
subnet_id = self.properties['SubnetId']
166
network_id = self.network_id_from_subnet_id(client, subnet_id)
167
@@ -80,18 +80,18 @@ class NetworkInterface(resource.Resource
168
self.resource_id_set(port['id'])
170
def handle_delete(self):
171
- from quantumclient.common.exceptions import QuantumClientException
172
+ from neutronclient.common.exceptions import NeutronClientException
174
- client = self.quantum()
175
+ client = self.neutron()
177
client.delete_port(self.resource_id)
178
- except QuantumClientException as ex:
179
+ except NeutronClientException as ex:
180
if ex.status_code != 404:
184
def resource_mapping():
185
- if clients.quantumclient is None:
186
+ if clients.neutronclient is None:
190
diff -Naurp heat-2013.2.b2.orig/heat/engine/resources/neutron/floatingip.py heat-2013.2.b2/heat/engine/resources/neutron/floatingip.py
191
--- heat-2013.2.b2.orig/heat/engine/resources/neutron/floatingip.py 1970-01-01 00:00:00.000000000 +0000
192
+++ heat-2013.2.b2/heat/engine/resources/neutron/floatingip.py 2013-08-07 22:24:21.099156844 +0000
194
+# vim: tabstop=4 shiftwidth=4 softtabstop=4
197
+# Licensed under the Apache License, Version 2.0 (the "License"); you may
198
+# not use this file except in compliance with the License. You may obtain
199
+# a copy of the License at
201
+# http://www.apache.org/licenses/LICENSE-2.0
203
+# Unless required by applicable law or agreed to in writing, software
204
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
205
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
206
+# License for the specific language governing permissions and limitations
207
+# under the License.
209
+from heat.engine import clients
210
+from heat.openstack.common import log as logging
211
+from heat.engine.resources.neutron import neutron
213
+if clients.neutronclient is not None:
214
+ from neutronclient.common.exceptions import NeutronClientException
216
+logger = logging.getLogger(__name__)
219
+class FloatingIP(neutron.NeutronResource):
220
+ properties_schema = {'floating_network_id': {'Type': 'String',
222
+ 'value_specs': {'Type': 'Map',
224
+ 'port_id': {'Type': 'String'},
225
+ 'fixed_ip_address': {'Type': 'String'}}
227
+ def add_dependencies(self, deps):
228
+ super(FloatingIP, self).add_dependencies(deps)
229
+ # depend on any RouterGateway in this template with the same
230
+ # network_id as this floating_network_id
231
+ for resource in self.stack.resources.itervalues():
232
+ if ((resource.type() == 'OS::Neutron::RouterGateway' or
233
+ resource.type() == 'OS::Quantum::RouterGateway') and
234
+ resource.properties.get('network_id') ==
235
+ self.properties.get('floating_network_id')):
236
+ deps += (self, resource)
238
+ def handle_create(self):
239
+ props = self.prepare_properties(
241
+ self.physical_resource_name())
242
+ fip = self.neutron().create_floatingip({
243
+ 'floatingip': props})['floatingip']
244
+ self.resource_id_set(fip['id'])
246
+ def handle_delete(self):
247
+ client = self.neutron()
249
+ client.delete_floatingip(self.resource_id)
250
+ except NeutronClientException as ex:
251
+ if ex.status_code != 404:
254
+ def FnGetAtt(self, key):
256
+ attributes = self.neutron().show_floatingip(
257
+ self.resource_id)['floatingip']
258
+ except NeutronClientException as ex:
259
+ logger.warn("failed to fetch resource attributes: %s" % str(ex))
261
+ return self.handle_get_attributes(self.name, key, attributes)
264
+class FloatingIPAssociation(neutron.NeutronResource):
265
+ properties_schema = {'floatingip_id': {'Type': 'String',
267
+ 'port_id': {'Type': 'String',
269
+ 'fixed_ip_address': {'Type': 'String'}}
271
+ def handle_create(self):
272
+ props = self.prepare_properties(self.properties, self.name)
274
+ floatingip_id = props.pop('floatingip_id')
276
+ self.neutron().update_floatingip(floatingip_id, {
277
+ 'floatingip': props})['floatingip']
278
+ self.resource_id_set('%s:%s' % (floatingip_id, props['port_id']))
280
+ def handle_delete(self):
281
+ if not self.resource_id:
283
+ client = self.neutron()
284
+ (floatingip_id, port_id) = self.resource_id.split(':')
286
+ client.update_floatingip(
288
+ {'floatingip': {'port_id': None}})
289
+ except NeutronClientException as ex:
290
+ if ex.status_code != 404:
294
+def resource_mapping():
295
+ if clients.neutronclient is None:
299
+ 'OS::Neutron::FloatingIP': FloatingIP,
300
+ 'OS::Neutron::FloatingIPAssociation': FloatingIPAssociation,
301
+ 'OS::Quantum::FloatingIP': FloatingIP,
302
+ 'OS::Quantum::FloatingIPAssociation': FloatingIPAssociation,
304
diff -Naurp heat-2013.2.b2.orig/heat/engine/resources/neutron/net.py heat-2013.2.b2/heat/engine/resources/neutron/net.py
305
--- heat-2013.2.b2.orig/heat/engine/resources/neutron/net.py 1970-01-01 00:00:00.000000000 +0000
306
+++ heat-2013.2.b2/heat/engine/resources/neutron/net.py 2013-08-07 22:24:21.099156844 +0000
308
+# vim: tabstop=4 shiftwidth=4 softtabstop=4
311
+# Licensed under the Apache License, Version 2.0 (the "License"); you may
312
+# not use this file except in compliance with the License. You may obtain
313
+# a copy of the License at
315
+# http://www.apache.org/licenses/LICENSE-2.0
317
+# Unless required by applicable law or agreed to in writing, software
318
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
319
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
320
+# License for the specific language governing permissions and limitations
321
+# under the License.
323
+from heat.engine import clients
324
+from heat.openstack.common import log as logging
325
+from heat.engine.resources.neutron import neutron
326
+from heat.engine import scheduler
328
+if clients.neutronclient is not None:
329
+ from neutronclient.common.exceptions import NeutronClientException
331
+logger = logging.getLogger(__name__)
334
+class Net(neutron.NeutronResource):
335
+ properties_schema = {'name': {'Type': 'String'},
336
+ 'value_specs': {'Type': 'Map',
338
+ 'admin_state_up': {'Default': True,
339
+ 'Type': 'Boolean'}}
340
+ attributes_schema = {
341
+ "id": "the unique identifier for this network",
342
+ "status": "the status of the network",
343
+ "name": "the name of the network",
344
+ "subnets": "subnets of this network",
345
+ "admin_state_up": "the administrative status of the network",
346
+ "tenant_id": "the tenant owning this network"
349
+ def handle_create(self):
350
+ props = self.prepare_properties(
352
+ self.physical_resource_name())
353
+ net = self.neutron().create_network({'network': props})['network']
354
+ self.resource_id_set(net['id'])
356
+ def _show_resource(self):
357
+ return self.neutron().show_network(
358
+ self.resource_id)['network']
360
+ def check_create_complete(self, *args):
361
+ attributes = self._show_resource()
362
+ return self.is_built(attributes)
364
+ def handle_delete(self):
365
+ client = self.neutron()
367
+ client.delete_network(self.resource_id)
368
+ except NeutronClientException as ex:
369
+ if ex.status_code != 404:
372
+ return scheduler.TaskRunner(self._confirm_delete)()
375
+def resource_mapping():
376
+ if clients.neutronclient is None:
380
+ 'OS::Neutron::Net': Net,
381
+ 'OS::Quantum::Net': Net,
383
diff -Naurp heat-2013.2.b2.orig/heat/engine/resources/neutron/neutron.py heat-2013.2.b2/heat/engine/resources/neutron/neutron.py
384
--- heat-2013.2.b2.orig/heat/engine/resources/neutron/neutron.py 1970-01-01 00:00:00.000000000 +0000
385
+++ heat-2013.2.b2/heat/engine/resources/neutron/neutron.py 2013-08-07 22:24:21.099156844 +0000
387
+# vim: tabstop=4 shiftwidth=4 softtabstop=4
390
+# Licensed under the Apache License, Version 2.0 (the "License"); you may
391
+# not use this file except in compliance with the License. You may obtain
392
+# a copy of the License at
394
+# http://www.apache.org/licenses/LICENSE-2.0
396
+# Unless required by applicable law or agreed to in writing, software
397
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
398
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
399
+# License for the specific language governing permissions and limitations
400
+# under the License.
402
+from neutronclient.common.exceptions import NeutronClientException
404
+from heat.common import exception
405
+from heat.engine import resource
407
+from heat.openstack.common import log as logging
409
+logger = logging.getLogger(__name__)
412
+class NeutronResource(resource.Resource):
414
+ def validate(self):
416
+ Validate any of the provided params
418
+ res = super(NeutronResource, self).validate()
421
+ return self.validate_properties(self.properties)
424
+ def validate_properties(properties):
426
+ Validates to ensure nothing in value_specs overwrites
427
+ any key that exists in the schema.
429
+ Also ensures that shared and tenant_id is not specified
432
+ if 'value_specs' in properties.keys():
433
+ vs = properties.get('value_specs')
434
+ banned_keys = set(['shared', 'tenant_id']).union(
436
+ for k in banned_keys.intersection(vs.keys()):
437
+ return '%s not allowed in value_specs' % k
440
+ def prepare_properties(properties, name):
442
+ Prepares the property values so that they can be passed directly to
445
+ Removes None values and value_specs, merges value_specs with the main
448
+ props = dict((k, v) for k, v in properties.items()
449
+ if v is not None and k != 'value_specs')
451
+ if 'name' in properties.keys():
452
+ props.setdefault('name', name)
454
+ if 'value_specs' in properties.keys():
455
+ props.update(properties.get('value_specs'))
460
+ def handle_get_attributes(name, key, attributes):
462
+ Support method for responding to FnGetAtt
467
+ if key in attributes.keys():
468
+ return attributes[key]
470
+ raise exception.InvalidTemplateAttribute(resource=name, key=key)
473
+ def is_built(attributes):
474
+ if attributes['status'] == 'BUILD':
476
+ if attributes['status'] in ('ACTIVE', 'DOWN'):
479
+ raise exception.Error('%s resource[%s] status[%s]' %
480
+ ('neutron reported unexpected',
481
+ attributes['name'], attributes['status']))
483
+ def _resolve_attribute(self, name):
485
+ attributes = self._show_resource()
486
+ except NeutronClientException as ex:
487
+ logger.warn("failed to fetch resource attributes: %s" % str(ex))
489
+ return self.handle_get_attributes(self.name, name, attributes)
491
+ def _confirm_delete(self):
495
+ self._show_resource()
496
+ except NeutronClientException as ex:
497
+ if ex.status_code != 404:
501
+ def FnGetRefId(self):
502
+ return unicode(self.resource_id)
503
diff -Naurp heat-2013.2.b2.orig/heat/engine/resources/neutron/port.py heat-2013.2.b2/heat/engine/resources/neutron/port.py
504
--- heat-2013.2.b2.orig/heat/engine/resources/neutron/port.py 1970-01-01 00:00:00.000000000 +0000
505
+++ heat-2013.2.b2/heat/engine/resources/neutron/port.py 2013-08-07 22:24:21.099156844 +0000
507
+# vim: tabstop=4 shiftwidth=4 softtabstop=4
510
+# Licensed under the Apache License, Version 2.0 (the "License"); you may
511
+# not use this file except in compliance with the License. You may obtain
512
+# a copy of the License at
514
+# http://www.apache.org/licenses/LICENSE-2.0
516
+# Unless required by applicable law or agreed to in writing, software
517
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
518
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
519
+# License for the specific language governing permissions and limitations
520
+# under the License.
522
+from heat.engine import clients
523
+from heat.openstack.common import log as logging
524
+from heat.engine.resources.neutron import neutron
525
+from heat.engine import scheduler
527
+if clients.neutronclient is not None:
528
+ from neutronclient.common.exceptions import NeutronClientException
530
+logger = logging.getLogger(__name__)
533
+class Port(neutron.NeutronResource):
535
+ fixed_ip_schema = {'subnet_id': {'Type': 'String',
537
+ 'ip_address': {'Type': 'String'}}
539
+ properties_schema = {'network_id': {'Type': 'String',
541
+ 'name': {'Type': 'String'},
542
+ 'value_specs': {'Type': 'Map',
544
+ 'admin_state_up': {'Default': True,
545
+ 'Type': 'Boolean'},
546
+ 'fixed_ips': {'Type': 'List',
547
+ 'Schema': {'Type': 'Map',
548
+ 'Schema': fixed_ip_schema}},
549
+ 'mac_address': {'Type': 'String'},
550
+ 'device_id': {'Type': 'String'},
551
+ 'security_groups': {'Type': 'List'}}
552
+ attributes_schema = {
553
+ "admin_state_up": "the administrative state of this port",
554
+ "device_id": "unique identifier for the device",
555
+ "device_owner": "name of the network owning the port",
556
+ "fixed_ips": "fixed ip addresses",
557
+ "id": "the unique identifier for the port",
558
+ "mac_address": "mac address of the port",
559
+ "name": "friendly name of the port",
560
+ "network_id": "unique identifier for the network owning the port",
561
+ "security_groups": "a list of security groups for the port",
562
+ "status": "the status of the port",
563
+ "tenant_id": "tenant owning the port"
566
+ def add_dependencies(self, deps):
567
+ super(Port, self).add_dependencies(deps)
568
+ # Depend on any Subnet in this template with the same
569
+ # network_id as this network_id.
570
+ # It is not known which subnet a port might be assigned
571
+ # to so all subnets in a network should be created before
572
+ # the ports in that network.
573
+ for resource in self.stack.resources.itervalues():
574
+ if ((resource.type() == 'OS::Neutron::Subnet' or
575
+ resource.type() == 'OS::Quantum::Subnet') and
576
+ resource.properties.get('network_id') ==
577
+ self.properties.get('network_id')):
578
+ deps += (self, resource)
580
+ def handle_create(self):
581
+ props = self.prepare_properties(
583
+ self.physical_resource_name())
584
+ port = self.neutron().create_port({'port': props})['port']
585
+ self.resource_id_set(port['id'])
587
+ def _show_resource(self):
588
+ return self.neutron().show_port(
589
+ self.resource_id)['port']
591
+ def check_create_complete(self, *args):
592
+ attributes = self._show_resource()
593
+ return self.is_built(attributes)
595
+ def handle_delete(self):
596
+ client = self.neutron()
598
+ client.delete_port(self.resource_id)
599
+ except NeutronClientException as ex:
600
+ if ex.status_code != 404:
603
+ return scheduler.TaskRunner(self._confirm_delete)()
606
+def resource_mapping():
607
+ if clients.neutronclient is None:
611
+ 'OS::Neutron::Port': Port,
612
+ 'OS::Quantum::Port': Port,
614
diff -Naurp heat-2013.2.b2.orig/heat/engine/resources/neutron/router.py heat-2013.2.b2/heat/engine/resources/neutron/router.py
615
--- heat-2013.2.b2.orig/heat/engine/resources/neutron/router.py 1970-01-01 00:00:00.000000000 +0000
616
+++ heat-2013.2.b2/heat/engine/resources/neutron/router.py 2013-08-07 22:24:21.099156844 +0000
618
+# vim: tabstop=4 shiftwidth=4 softtabstop=4
621
+# Licensed under the Apache License, Version 2.0 (the "License"); you may
622
+# not use this file except in compliance with the License. You may obtain
623
+# a copy of the License at
625
+# http://www.apache.org/licenses/LICENSE-2.0
627
+# Unless required by applicable law or agreed to in writing, software
628
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
629
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
630
+# License for the specific language governing permissions and limitations
631
+# under the License.
633
+from heat.engine import clients
634
+from heat.engine.resources.neutron import neutron
635
+from heat.engine import scheduler
637
+if clients.neutronclient is not None:
638
+ from neutronclient.common.exceptions import NeutronClientException
640
+from heat.openstack.common import log as logging
642
+logger = logging.getLogger(__name__)
645
+class Router(neutron.NeutronResource):
646
+ properties_schema = {'name': {'Type': 'String'},
647
+ 'value_specs': {'Type': 'Map',
649
+ 'admin_state_up': {'Type': 'Boolean',
651
+ attributes_schema = {
652
+ "status": "the status of the router",
653
+ "external_gateway_info": "gateway network for the router",
654
+ "name": "friendly name of the router",
655
+ "admin_state_up": "administrative state of the router",
656
+ "tenant_id": "tenant owning the router",
657
+ "id": "unique identifier for the router"
660
+ def handle_create(self):
661
+ props = self.prepare_properties(
663
+ self.physical_resource_name())
664
+ router = self.neutron().create_router({'router': props})['router']
665
+ self.resource_id_set(router['id'])
667
+ def _show_resource(self):
668
+ return self.neutron().show_router(
669
+ self.resource_id)['router']
671
+ def check_create_complete(self, *args):
672
+ attributes = self._show_resource()
673
+ return self.is_built(attributes)
675
+ def handle_delete(self):
676
+ client = self.neutron()
678
+ client.delete_router(self.resource_id)
679
+ except NeutronClientException as ex:
680
+ if ex.status_code != 404:
683
+ return scheduler.TaskRunner(self._confirm_delete)()
686
+class RouterInterface(neutron.NeutronResource):
687
+ properties_schema = {'router_id': {'Type': 'String',
689
+ 'subnet_id': {'Type': 'String',
692
+ def handle_create(self):
693
+ router_id = self.properties.get('router_id')
694
+ subnet_id = self.properties.get('subnet_id')
695
+ self.neutron().add_interface_router(
697
+ {'subnet_id': subnet_id})
698
+ self.resource_id_set('%s:%s' % (router_id, subnet_id))
700
+ def handle_delete(self):
701
+ client = self.neutron()
702
+ (router_id, subnet_id) = self.resource_id.split(':')
704
+ client.remove_interface_router(
706
+ {'subnet_id': subnet_id})
707
+ except NeutronClientException as ex:
708
+ if ex.status_code != 404:
712
+class RouterGateway(neutron.NeutronResource):
713
+ properties_schema = {'router_id': {'Type': 'String',
715
+ 'network_id': {'Type': 'String',
718
+ def add_dependencies(self, deps):
719
+ super(RouterGateway, self).add_dependencies(deps)
720
+ for resource in self.stack.resources.itervalues():
721
+ # depend on any RouterInterface in this template with the same
722
+ # router_id as this router_id
723
+ if ((resource.type() == 'OS::Neutron::RouterInterface' or
724
+ resource.type() == 'OS::Quantum::RouterInterface') and
725
+ resource.properties.get('router_id') ==
726
+ self.properties.get('router_id')):
727
+ deps += (self, resource)
728
+ # depend on any subnet in this template with the same network_id
729
+ # as this network_id, as the gateway implicitly creates a port
731
+ elif ((resource.type() == 'OS::Neutron::Subnet' or
732
+ resource.type() == 'OS::Quantum::Subnet') and
733
+ resource.properties.get('network_id') ==
734
+ self.properties.get('network_id')):
735
+ deps += (self, resource)
737
+ def handle_create(self):
738
+ router_id = self.properties.get('router_id')
739
+ network_id = self.properties.get('network_id')
740
+ self.neutron().add_gateway_router(
742
+ {'network_id': network_id})
743
+ self.resource_id_set('%s:%s' % (router_id, network_id))
745
+ def handle_delete(self):
746
+ client = self.neutron()
747
+ (router_id, network_id) = self.resource_id.split(':')
749
+ client.remove_gateway_router(router_id)
750
+ except NeutronClientException as ex:
751
+ if ex.status_code != 404:
755
+def resource_mapping():
756
+ if clients.neutronclient is None:
760
+ 'OS::Neutron::Router': Router,
761
+ 'OS::Neutron::RouterInterface': RouterInterface,
762
+ 'OS::Neutron::RouterGateway': RouterGateway,
763
+ 'OS::Quantum::Router': Router,
764
+ 'OS::Quantum::RouterInterface': RouterInterface,
765
+ 'OS::Quantum::RouterGateway': RouterGateway,
767
diff -Naurp heat-2013.2.b2.orig/heat/engine/resources/neutron/subnet.py heat-2013.2.b2/heat/engine/resources/neutron/subnet.py
768
--- heat-2013.2.b2.orig/heat/engine/resources/neutron/subnet.py 1970-01-01 00:00:00.000000000 +0000
769
+++ heat-2013.2.b2/heat/engine/resources/neutron/subnet.py 2013-08-07 22:24:21.099156844 +0000
771
+# vim: tabstop=4 shiftwidth=4 softtabstop=4
774
+# Licensed under the Apache License, Version 2.0 (the "License"); you may
775
+# not use this file except in compliance with the License. You may obtain
776
+# a copy of the License at
778
+# http://www.apache.org/licenses/LICENSE-2.0
780
+# Unless required by applicable law or agreed to in writing, software
781
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
782
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
783
+# License for the specific language governing permissions and limitations
784
+# under the License.
786
+from heat.engine import clients
787
+from heat.openstack.common import log as logging
788
+from heat.engine.resources.neutron import neutron
789
+from heat.engine import scheduler
791
+if clients.neutronclient is not None:
792
+ from neutronclient.common.exceptions import NeutronClientException
794
+logger = logging.getLogger(__name__)
797
+class Subnet(neutron.NeutronResource):
799
+ allocation_schema = {'start': {'Type': 'String',
801
+ 'end': {'Type': 'String',
804
+ properties_schema = {'network_id': {'Type': 'String',
806
+ 'cidr': {'Type': 'String',
808
+ 'value_specs': {'Type': 'Map',
810
+ 'name': {'Type': 'String'},
811
+ 'ip_version': {'Type': 'Integer',
812
+ 'AllowedValues': [4, 6],
814
+ 'dns_nameservers': {'Type': 'List'},
815
+ 'gateway_ip': {'Type': 'String'},
816
+ 'enable_dhcp': {'Type': 'Boolean'},
817
+ 'allocation_pools': {'Type': 'List',
820
+ 'Schema': allocation_schema
822
+ attributes_schema = {
823
+ "name": "friendly name of the subnet",
824
+ "network_id": "parent network of the subnet",
825
+ "tenant_id": "tenant owning the subnet",
826
+ "allocation_pools": "ip allocation pools and their ranges",
827
+ "gateway_ip": "ip of the subnet's gateway",
828
+ "ip_version": "ip version for the subnet",
829
+ "cidr": "CIDR block notation for this subnet",
830
+ "id": "unique identifier for this subnet",
831
+ # dns_nameservers isn't in the api docs; is it right?
832
+ "dns_nameservers": "list of dns nameservers",
833
+ "enable_dhcp": ("'true' if DHCP is enabled for this subnet; 'false'"
837
+ def handle_create(self):
838
+ props = self.prepare_properties(
840
+ self.physical_resource_name())
841
+ subnet = self.neutron().create_subnet({'subnet': props})['subnet']
842
+ self.resource_id_set(subnet['id'])
844
+ def handle_delete(self):
845
+ client = self.neutron()
847
+ client.delete_subnet(self.resource_id)
848
+ except NeutronClientException as ex:
849
+ if ex.status_code != 404:
852
+ return scheduler.TaskRunner(self._confirm_delete)()
854
+ def _show_resource(self):
855
+ return self.neutron().show_subnet(self.resource_id)['subnet']
858
+def resource_mapping():
859
+ if clients.neutronclient is None:
863
+ 'OS::Neutron::Subnet': Subnet,
864
+ 'OS::Quantum::Subnet': Subnet,
866
diff -Naurp heat-2013.2.b2.orig/heat/engine/resources/quantum/floatingip.py heat-2013.2.b2/heat/engine/resources/quantum/floatingip.py
867
--- heat-2013.2.b2.orig/heat/engine/resources/quantum/floatingip.py 2013-08-07 22:22:07.379156844 +0000
868
+++ heat-2013.2.b2/heat/engine/resources/quantum/floatingip.py 1970-01-01 00:00:00.000000000 +0000
870
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
873
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
874
-# not use this file except in compliance with the License. You may obtain
875
-# a copy of the License at
877
-# http://www.apache.org/licenses/LICENSE-2.0
879
-# Unless required by applicable law or agreed to in writing, software
880
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
881
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
882
-# License for the specific language governing permissions and limitations
883
-# under the License.
885
-from heat.engine import clients
886
-from heat.openstack.common import log as logging
887
-from heat.engine.resources.quantum import quantum
889
-if clients.quantumclient is not None:
890
- from quantumclient.common.exceptions import QuantumClientException
892
-logger = logging.getLogger(__name__)
895
-class FloatingIP(quantum.QuantumResource):
896
- properties_schema = {'floating_network_id': {'Type': 'String',
898
- 'value_specs': {'Type': 'Map',
900
- 'port_id': {'Type': 'String'},
901
- 'fixed_ip_address': {'Type': 'String'}}
903
- def add_dependencies(self, deps):
904
- super(FloatingIP, self).add_dependencies(deps)
905
- # depend on any RouterGateway in this template with the same
906
- # network_id as this floating_network_id
907
- for resource in self.stack.resources.itervalues():
908
- if (resource.type() == 'OS::Quantum::RouterGateway' and
909
- resource.properties.get('network_id') ==
910
- self.properties.get('floating_network_id')):
911
- deps += (self, resource)
913
- def handle_create(self):
914
- props = self.prepare_properties(
916
- self.physical_resource_name())
917
- fip = self.quantum().create_floatingip({
918
- 'floatingip': props})['floatingip']
919
- self.resource_id_set(fip['id'])
921
- def handle_delete(self):
922
- client = self.quantum()
924
- client.delete_floatingip(self.resource_id)
925
- except QuantumClientException as ex:
926
- if ex.status_code != 404:
929
- def FnGetAtt(self, key):
931
- attributes = self.quantum().show_floatingip(
932
- self.resource_id)['floatingip']
933
- except QuantumClientException as ex:
934
- logger.warn("failed to fetch resource attributes: %s" % str(ex))
936
- return self.handle_get_attributes(self.name, key, attributes)
939
-class FloatingIPAssociation(quantum.QuantumResource):
940
- properties_schema = {'floatingip_id': {'Type': 'String',
942
- 'port_id': {'Type': 'String',
944
- 'fixed_ip_address': {'Type': 'String'}}
946
- def handle_create(self):
947
- props = self.prepare_properties(self.properties, self.name)
949
- floatingip_id = props.pop('floatingip_id')
951
- self.quantum().update_floatingip(floatingip_id, {
952
- 'floatingip': props})['floatingip']
953
- self.resource_id_set('%s:%s' % (floatingip_id, props['port_id']))
955
- def handle_delete(self):
956
- if not self.resource_id:
958
- client = self.quantum()
959
- (floatingip_id, port_id) = self.resource_id.split(':')
961
- client.update_floatingip(
963
- {'floatingip': {'port_id': None}})
964
- except QuantumClientException as ex:
965
- if ex.status_code != 404:
969
-def resource_mapping():
970
- if clients.quantumclient is None:
974
- 'OS::Quantum::FloatingIP': FloatingIP,
975
- 'OS::Quantum::FloatingIPAssociation': FloatingIPAssociation,
977
diff -Naurp heat-2013.2.b2.orig/heat/engine/resources/quantum/net.py heat-2013.2.b2/heat/engine/resources/quantum/net.py
978
--- heat-2013.2.b2.orig/heat/engine/resources/quantum/net.py 2013-08-07 22:22:07.379156844 +0000
979
+++ heat-2013.2.b2/heat/engine/resources/quantum/net.py 1970-01-01 00:00:00.000000000 +0000
981
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
984
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
985
-# not use this file except in compliance with the License. You may obtain
986
-# a copy of the License at
988
-# http://www.apache.org/licenses/LICENSE-2.0
990
-# Unless required by applicable law or agreed to in writing, software
991
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
992
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
993
-# License for the specific language governing permissions and limitations
994
-# under the License.
996
-from heat.engine import clients
997
-from heat.openstack.common import log as logging
998
-from heat.engine.resources.quantum import quantum
999
-from heat.engine import scheduler
1001
-if clients.quantumclient is not None:
1002
- from quantumclient.common.exceptions import QuantumClientException
1004
-logger = logging.getLogger(__name__)
1007
-class Net(quantum.QuantumResource):
1008
- properties_schema = {'name': {'Type': 'String'},
1009
- 'value_specs': {'Type': 'Map',
1011
- 'admin_state_up': {'Default': True,
1012
- 'Type': 'Boolean'}}
1013
- attributes_schema = {
1014
- "id": "the unique identifier for this network",
1015
- "status": "the status of the network",
1016
- "name": "the name of the network",
1017
- "subnets": "subnets of this network",
1018
- "admin_state_up": "the administrative status of the network",
1019
- "tenant_id": "the tenant owning this network"
1022
- def handle_create(self):
1023
- props = self.prepare_properties(
1025
- self.physical_resource_name())
1026
- net = self.quantum().create_network({'network': props})['network']
1027
- self.resource_id_set(net['id'])
1029
- def _show_resource(self):
1030
- return self.quantum().show_network(
1031
- self.resource_id)['network']
1033
- def check_create_complete(self, *args):
1034
- attributes = self._show_resource()
1035
- return self.is_built(attributes)
1037
- def handle_delete(self):
1038
- client = self.quantum()
1040
- client.delete_network(self.resource_id)
1041
- except QuantumClientException as ex:
1042
- if ex.status_code != 404:
1045
- return scheduler.TaskRunner(self._confirm_delete)()
1048
-def resource_mapping():
1049
- if clients.quantumclient is None:
1053
- 'OS::Quantum::Net': Net,
1055
diff -Naurp heat-2013.2.b2.orig/heat/engine/resources/quantum/port.py heat-2013.2.b2/heat/engine/resources/quantum/port.py
1056
--- heat-2013.2.b2.orig/heat/engine/resources/quantum/port.py 2013-08-07 22:22:07.379156844 +0000
1057
+++ heat-2013.2.b2/heat/engine/resources/quantum/port.py 1970-01-01 00:00:00.000000000 +0000
1059
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
1062
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
1063
-# not use this file except in compliance with the License. You may obtain
1064
-# a copy of the License at
1066
-# http://www.apache.org/licenses/LICENSE-2.0
1068
-# Unless required by applicable law or agreed to in writing, software
1069
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
1070
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
1071
-# License for the specific language governing permissions and limitations
1072
-# under the License.
1074
-from heat.engine import clients
1075
-from heat.openstack.common import log as logging
1076
-from heat.engine.resources.quantum import quantum
1077
-from heat.engine import scheduler
1079
-if clients.quantumclient is not None:
1080
- from quantumclient.common.exceptions import QuantumClientException
1082
-logger = logging.getLogger(__name__)
1085
-class Port(quantum.QuantumResource):
1087
- fixed_ip_schema = {'subnet_id': {'Type': 'String',
1088
- 'Required': True},
1089
- 'ip_address': {'Type': 'String'}}
1091
- properties_schema = {'network_id': {'Type': 'String',
1092
- 'Required': True},
1093
- 'name': {'Type': 'String'},
1094
- 'value_specs': {'Type': 'Map',
1096
- 'admin_state_up': {'Default': True,
1097
- 'Type': 'Boolean'},
1098
- 'fixed_ips': {'Type': 'List',
1099
- 'Schema': {'Type': 'Map',
1100
- 'Schema': fixed_ip_schema}},
1101
- 'mac_address': {'Type': 'String'},
1102
- 'device_id': {'Type': 'String'},
1103
- 'security_groups': {'Type': 'List'}}
1104
- attributes_schema = {
1105
- "admin_state_up": "the administrative state of this port",
1106
- "device_id": "unique identifier for the device",
1107
- "device_owner": "name of the network owning the port",
1108
- "fixed_ips": "fixed ip addresses",
1109
- "id": "the unique identifier for the port",
1110
- "mac_address": "mac address of the port",
1111
- "name": "friendly name of the port",
1112
- "network_id": "unique identifier for the network owning the port",
1113
- "security_groups": "a list of security groups for the port",
1114
- "status": "the status of the port",
1115
- "tenant_id": "tenant owning the port"
1118
- def add_dependencies(self, deps):
1119
- super(Port, self).add_dependencies(deps)
1120
- # Depend on any Subnet in this template with the same
1121
- # network_id as this network_id.
1122
- # It is not known which subnet a port might be assigned
1123
- # to so all subnets in a network should be created before
1124
- # the ports in that network.
1125
- for resource in self.stack.resources.itervalues():
1126
- if (resource.type() == 'OS::Quantum::Subnet' and
1127
- resource.properties.get('network_id') ==
1128
- self.properties.get('network_id')):
1129
- deps += (self, resource)
1131
- def handle_create(self):
1132
- props = self.prepare_properties(
1134
- self.physical_resource_name())
1135
- port = self.quantum().create_port({'port': props})['port']
1136
- self.resource_id_set(port['id'])
1138
- def _show_resource(self):
1139
- return self.quantum().show_port(
1140
- self.resource_id)['port']
1142
- def check_create_complete(self, *args):
1143
- attributes = self._show_resource()
1144
- return self.is_built(attributes)
1146
- def handle_delete(self):
1147
- client = self.quantum()
1149
- client.delete_port(self.resource_id)
1150
- except QuantumClientException as ex:
1151
- if ex.status_code != 404:
1154
- return scheduler.TaskRunner(self._confirm_delete)()
1157
-def resource_mapping():
1158
- if clients.quantumclient is None:
1162
- 'OS::Quantum::Port': Port,
1164
diff -Naurp heat-2013.2.b2.orig/heat/engine/resources/quantum/quantum.py heat-2013.2.b2/heat/engine/resources/quantum/quantum.py
1165
--- heat-2013.2.b2.orig/heat/engine/resources/quantum/quantum.py 2013-08-07 22:22:07.379156844 +0000
1166
+++ heat-2013.2.b2/heat/engine/resources/quantum/quantum.py 1970-01-01 00:00:00.000000000 +0000
1168
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
1171
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
1172
-# not use this file except in compliance with the License. You may obtain
1173
-# a copy of the License at
1175
-# http://www.apache.org/licenses/LICENSE-2.0
1177
-# Unless required by applicable law or agreed to in writing, software
1178
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
1179
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
1180
-# License for the specific language governing permissions and limitations
1181
-# under the License.
1183
-from quantumclient.common.exceptions import QuantumClientException
1185
-from heat.common import exception
1186
-from heat.engine import resource
1188
-from heat.openstack.common import log as logging
1190
-logger = logging.getLogger(__name__)
1193
-class QuantumResource(resource.Resource):
1195
- def validate(self):
1197
- Validate any of the provided params
1199
- res = super(QuantumResource, self).validate()
1202
- return self.validate_properties(self.properties)
1205
- def validate_properties(properties):
1207
- Validates to ensure nothing in value_specs overwrites
1208
- any key that exists in the schema.
1210
- Also ensures that shared and tenant_id is not specified
1213
- if 'value_specs' in properties.keys():
1214
- vs = properties.get('value_specs')
1215
- banned_keys = set(['shared', 'tenant_id']).union(
1216
- properties.keys())
1217
- for k in banned_keys.intersection(vs.keys()):
1218
- return '%s not allowed in value_specs' % k
1221
- def prepare_properties(properties, name):
1223
- Prepares the property values so that they can be passed directly to
1226
- Removes None values and value_specs, merges value_specs with the main
1229
- props = dict((k, v) for k, v in properties.items()
1230
- if v is not None and k != 'value_specs')
1232
- if 'name' in properties.keys():
1233
- props.setdefault('name', name)
1235
- if 'value_specs' in properties.keys():
1236
- props.update(properties.get('value_specs'))
1241
- def handle_get_attributes(name, key, attributes):
1243
- Support method for responding to FnGetAtt
1248
- if key in attributes.keys():
1249
- return attributes[key]
1251
- raise exception.InvalidTemplateAttribute(resource=name, key=key)
1254
- def is_built(attributes):
1255
- if attributes['status'] == 'BUILD':
1257
- if attributes['status'] in ('ACTIVE', 'DOWN'):
1260
- raise exception.Error('%s resource[%s] status[%s]' %
1261
- ('quantum reported unexpected',
1262
- attributes['name'], attributes['status']))
1264
- def _resolve_attribute(self, name):
1266
- attributes = self._show_resource()
1267
- except QuantumClientException as ex:
1268
- logger.warn("failed to fetch resource attributes: %s" % str(ex))
1270
- return self.handle_get_attributes(self.name, name, attributes)
1272
- def _confirm_delete(self):
1276
- self._show_resource()
1277
- except QuantumClientException as ex:
1278
- if ex.status_code != 404:
1282
- def FnGetRefId(self):
1283
- return unicode(self.resource_id)
1284
diff -Naurp heat-2013.2.b2.orig/heat/engine/resources/quantum/router.py heat-2013.2.b2/heat/engine/resources/quantum/router.py
1285
--- heat-2013.2.b2.orig/heat/engine/resources/quantum/router.py 2013-08-07 22:22:07.379156844 +0000
1286
+++ heat-2013.2.b2/heat/engine/resources/quantum/router.py 1970-01-01 00:00:00.000000000 +0000
1288
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
1291
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
1292
-# not use this file except in compliance with the License. You may obtain
1293
-# a copy of the License at
1295
-# http://www.apache.org/licenses/LICENSE-2.0
1297
-# Unless required by applicable law or agreed to in writing, software
1298
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
1299
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
1300
-# License for the specific language governing permissions and limitations
1301
-# under the License.
1303
-from heat.engine import clients
1304
-from heat.engine.resources.quantum import quantum
1305
-from heat.engine import scheduler
1307
-if clients.quantumclient is not None:
1308
- from quantumclient.common.exceptions import QuantumClientException
1310
-from heat.openstack.common import log as logging
1312
-logger = logging.getLogger(__name__)
1315
-class Router(quantum.QuantumResource):
1316
- properties_schema = {'name': {'Type': 'String'},
1317
- 'value_specs': {'Type': 'Map',
1319
- 'admin_state_up': {'Type': 'Boolean',
1321
- attributes_schema = {
1322
- "status": "the status of the router",
1323
- "external_gateway_info": "gateway network for the router",
1324
- "name": "friendly name of the router",
1325
- "admin_state_up": "administrative state of the router",
1326
- "tenant_id": "tenant owning the router",
1327
- "id": "unique identifier for the router"
1330
- def handle_create(self):
1331
- props = self.prepare_properties(
1333
- self.physical_resource_name())
1334
- router = self.quantum().create_router({'router': props})['router']
1335
- self.resource_id_set(router['id'])
1337
- def _show_resource(self):
1338
- return self.quantum().show_router(
1339
- self.resource_id)['router']
1341
- def check_create_complete(self, *args):
1342
- attributes = self._show_resource()
1343
- return self.is_built(attributes)
1345
- def handle_delete(self):
1346
- client = self.quantum()
1348
- client.delete_router(self.resource_id)
1349
- except QuantumClientException as ex:
1350
- if ex.status_code != 404:
1353
- return scheduler.TaskRunner(self._confirm_delete)()
1356
-class RouterInterface(quantum.QuantumResource):
1357
- properties_schema = {'router_id': {'Type': 'String',
1358
- 'Required': True},
1359
- 'subnet_id': {'Type': 'String',
1360
- 'Required': True}}
1362
- def handle_create(self):
1363
- router_id = self.properties.get('router_id')
1364
- subnet_id = self.properties.get('subnet_id')
1365
- self.quantum().add_interface_router(
1367
- {'subnet_id': subnet_id})
1368
- self.resource_id_set('%s:%s' % (router_id, subnet_id))
1370
- def handle_delete(self):
1371
- client = self.quantum()
1372
- (router_id, subnet_id) = self.resource_id.split(':')
1374
- client.remove_interface_router(
1376
- {'subnet_id': subnet_id})
1377
- except QuantumClientException as ex:
1378
- if ex.status_code != 404:
1382
-class RouterGateway(quantum.QuantumResource):
1383
- properties_schema = {'router_id': {'Type': 'String',
1384
- 'Required': True},
1385
- 'network_id': {'Type': 'String',
1386
- 'Required': True}}
1388
- def add_dependencies(self, deps):
1389
- super(RouterGateway, self).add_dependencies(deps)
1390
- for resource in self.stack.resources.itervalues():
1391
- # depend on any RouterInterface in this template with the same
1392
- # router_id as this router_id
1393
- if (resource.type() == 'OS::Quantum::RouterInterface' and
1394
- resource.properties.get('router_id') ==
1395
- self.properties.get('router_id')):
1396
- deps += (self, resource)
1397
- # depend on any subnet in this template with the same network_id
1398
- # as this network_id, as the gateway implicitly creates a port
1400
- elif (resource.type() == 'OS::Quantum::Subnet' and
1401
- resource.properties.get('network_id') ==
1402
- self.properties.get('network_id')):
1403
- deps += (self, resource)
1405
- def handle_create(self):
1406
- router_id = self.properties.get('router_id')
1407
- network_id = self.properties.get('network_id')
1408
- self.quantum().add_gateway_router(
1410
- {'network_id': network_id})
1411
- self.resource_id_set('%s:%s' % (router_id, network_id))
1413
- def handle_delete(self):
1414
- client = self.quantum()
1415
- (router_id, network_id) = self.resource_id.split(':')
1417
- client.remove_gateway_router(router_id)
1418
- except QuantumClientException as ex:
1419
- if ex.status_code != 404:
1423
-def resource_mapping():
1424
- if clients.quantumclient is None:
1428
- 'OS::Quantum::Router': Router,
1429
- 'OS::Quantum::RouterInterface': RouterInterface,
1430
- 'OS::Quantum::RouterGateway': RouterGateway,
1432
diff -Naurp heat-2013.2.b2.orig/heat/engine/resources/quantum/subnet.py heat-2013.2.b2/heat/engine/resources/quantum/subnet.py
1433
--- heat-2013.2.b2.orig/heat/engine/resources/quantum/subnet.py 2013-08-07 22:22:07.379156844 +0000
1434
+++ heat-2013.2.b2/heat/engine/resources/quantum/subnet.py 1970-01-01 00:00:00.000000000 +0000
1436
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
1439
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
1440
-# not use this file except in compliance with the License. You may obtain
1441
-# a copy of the License at
1443
-# http://www.apache.org/licenses/LICENSE-2.0
1445
-# Unless required by applicable law or agreed to in writing, software
1446
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
1447
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
1448
-# License for the specific language governing permissions and limitations
1449
-# under the License.
1451
-from heat.engine import clients
1452
-from heat.openstack.common import log as logging
1453
-from heat.engine.resources.quantum import quantum
1454
-from heat.engine import scheduler
1456
-if clients.quantumclient is not None:
1457
- from quantumclient.common.exceptions import QuantumClientException
1459
-logger = logging.getLogger(__name__)
1462
-class Subnet(quantum.QuantumResource):
1464
- allocation_schema = {'start': {'Type': 'String',
1465
- 'Required': True},
1466
- 'end': {'Type': 'String',
1467
- 'Required': True}}
1469
- properties_schema = {'network_id': {'Type': 'String',
1470
- 'Required': True},
1471
- 'cidr': {'Type': 'String',
1472
- 'Required': True},
1473
- 'value_specs': {'Type': 'Map',
1475
- 'name': {'Type': 'String'},
1476
- 'ip_version': {'Type': 'Integer',
1477
- 'AllowedValues': [4, 6],
1479
- 'dns_nameservers': {'Type': 'List'},
1480
- 'gateway_ip': {'Type': 'String'},
1481
- 'enable_dhcp': {'Type': 'Boolean'},
1482
- 'allocation_pools': {'Type': 'List',
1485
- 'Schema': allocation_schema
1487
- attributes_schema = {
1488
- "name": "friendly name of the subnet",
1489
- "network_id": "parent network of the subnet",
1490
- "tenant_id": "tenant owning the subnet",
1491
- "allocation_pools": "ip allocation pools and their ranges",
1492
- "gateway_ip": "ip of the subnet's gateway",
1493
- "ip_version": "ip version for the subnet",
1494
- "cidr": "CIDR block notation for this subnet",
1495
- "id": "unique identifier for this subnet",
1496
- # dns_nameservers isn't in the api docs; is it right?
1497
- "dns_nameservers": "list of dns nameservers",
1498
- "enable_dhcp": ("'true' if DHCP is enabled for this subnet; 'false'"
1502
- def handle_create(self):
1503
- props = self.prepare_properties(
1505
- self.physical_resource_name())
1506
- subnet = self.quantum().create_subnet({'subnet': props})['subnet']
1507
- self.resource_id_set(subnet['id'])
1509
- def handle_delete(self):
1510
- client = self.quantum()
1512
- client.delete_subnet(self.resource_id)
1513
- except QuantumClientException as ex:
1514
- if ex.status_code != 404:
1517
- return scheduler.TaskRunner(self._confirm_delete)()
1519
- def _show_resource(self):
1520
- return self.quantum().show_subnet(self.resource_id)['subnet']
1523
-def resource_mapping():
1524
- if clients.quantumclient is None:
1528
- 'OS::Quantum::Subnet': Subnet,
1530
diff -Naurp heat-2013.2.b2.orig/heat/engine/resources/rackspace/rackspace_resource.py heat-2013.2.b2/heat/engine/resources/rackspace/rackspace_resource.py
1531
--- heat-2013.2.b2.orig/heat/engine/resources/rackspace/rackspace_resource.py 2013-08-07 22:22:07.379156844 +0000
1532
+++ heat-2013.2.b2/heat/engine/resources/rackspace/rackspace_resource.py 2013-08-07 22:24:21.099156844 +0000
1533
@@ -83,8 +83,8 @@ class RackspaceResource(resource.Resourc
1535
return self._cloud_blockstore
1537
- def quantum(self):
1538
- '''Rackspace quantum client.'''
1539
+ def neutron(self):
1540
+ '''Rackspace neutron client.'''
1541
if not self._cloud_nw:
1542
self.__authenticate()
1543
self._cloud_nw = self.pyrax.cloud_networks
1544
diff -Naurp heat-2013.2.b2.orig/heat/engine/resources/route_table.py heat-2013.2.b2/heat/engine/resources/route_table.py
1545
--- heat-2013.2.b2.orig/heat/engine/resources/route_table.py 2013-08-07 22:22:07.379156844 +0000
1546
+++ heat-2013.2.b2/heat/engine/resources/route_table.py 2013-08-07 22:24:21.107156844 +0000
1548
from heat.engine import clients
1549
from heat.openstack.common import log as logging
1550
from heat.engine import resource
1551
-from heat.engine.resources.quantum import quantum
1552
+from heat.engine.resources.neutron import neutron
1553
from heat.engine.resources.vpc import VPC
1555
-if clients.quantumclient is not None:
1556
- from quantumclient.common.exceptions import QuantumClientException
1557
+if clients.neutronclient is not None:
1558
+ from neutronclient.common.exceptions import NeutronClientException
1560
logger = logging.getLogger(__name__)
1562
@@ -42,16 +42,16 @@ class RouteTable(resource.Resource):
1565
def handle_create(self):
1566
- client = self.quantum()
1567
+ client = self.neutron()
1568
props = {'name': self.physical_resource_name()}
1569
router = client.create_router({'router': props})['router']
1570
self.resource_id_set(router['id'])
1572
def check_create_complete(self, *args):
1573
- client = self.quantum()
1574
+ client = self.neutron()
1575
attributes = client.show_router(
1576
self.resource_id)['router']
1577
- if not quantum.QuantumResource.is_built(attributes):
1578
+ if not neutron.NeutronResource.is_built(attributes):
1581
network_id = self.properties.get('VpcId')
1582
@@ -66,19 +66,19 @@ class RouteTable(resource.Resource):
1585
def handle_delete(self):
1586
- client = self.quantum()
1587
+ client = self.neutron()
1589
router_id = self.resource_id
1591
client.delete_router(router_id)
1592
- except QuantumClientException as ex:
1593
+ except NeutronClientException as ex:
1594
if ex.status_code != 404:
1597
# just in case this router has been added to a gateway, remove it
1599
client.remove_gateway_router(router_id)
1600
- except QuantumClientException as ex:
1601
+ except NeutronClientException as ex:
1602
if ex.status_code != 404:
1605
@@ -95,7 +95,7 @@ class SubnetRouteTableAssocation(resourc
1608
def handle_create(self):
1609
- client = self.quantum()
1610
+ client = self.neutron()
1611
subnet_id = self.properties.get('SubnetId')
1613
router_id = self.properties.get('RouteTableId')
1614
@@ -107,7 +107,7 @@ class SubnetRouteTableAssocation(resourc
1615
client.remove_interface_router(
1616
previous_router['id'],
1617
{'subnet_id': subnet_id})
1618
- except QuantumClientException as ex:
1619
+ except NeutronClientException as ex:
1620
if ex.status_code != 404:
1623
@@ -115,14 +115,14 @@ class SubnetRouteTableAssocation(resourc
1624
router_id, {'subnet_id': subnet_id})
1626
def _router_for_subnet(self, subnet_id):
1627
- client = self.quantum()
1628
+ client = self.neutron()
1629
subnet = client.show_subnet(
1630
subnet_id)['subnet']
1631
network_id = subnet['network_id']
1632
return VPC.router_for_vpc(client, network_id)
1634
def handle_delete(self):
1635
- client = self.quantum()
1636
+ client = self.neutron()
1637
subnet_id = self.properties.get('SubnetId')
1639
router_id = self.properties.get('RouteTableId')
1640
@@ -130,7 +130,7 @@ class SubnetRouteTableAssocation(resourc
1642
client.remove_interface_router(router_id, {
1643
'subnet_id': subnet_id})
1644
- except QuantumClientException as ex:
1645
+ except NeutronClientException as ex:
1646
if ex.status_code != 404:
1649
@@ -140,13 +140,13 @@ class SubnetRouteTableAssocation(resourc
1651
client.add_interface_router(
1652
default_router['id'], {'subnet_id': subnet_id})
1653
- except QuantumClientException as ex:
1654
+ except NeutronClientException as ex:
1655
if ex.status_code != 404:
1659
def resource_mapping():
1660
- if clients.quantumclient is None:
1661
+ if clients.neutronclient is None:
1665
diff -Naurp heat-2013.2.b2.orig/heat/engine/resources/security_group.py heat-2013.2.b2/heat/engine/resources/security_group.py
1666
--- heat-2013.2.b2.orig/heat/engine/resources/security_group.py 2013-08-07 22:22:07.379156844 +0000
1667
+++ heat-2013.2.b2/heat/engine/resources/security_group.py 2013-08-07 22:24:21.107156844 +0000
1668
@@ -29,14 +29,14 @@ class SecurityGroup(resource.Resource):
1669
'SecurityGroupEgress': {'Type': 'List'}}
1671
def handle_create(self):
1672
- if self.properties['VpcId'] and clients.quantumclient is not None:
1673
- self._handle_create_quantum()
1674
+ if self.properties['VpcId'] and clients.neutronclient is not None:
1675
+ self._handle_create_neutron()
1677
self._handle_create_nova()
1679
- def _handle_create_quantum(self):
1680
- from quantumclient.common.exceptions import QuantumClientException
1681
- client = self.quantum()
1682
+ def _handle_create_neutron(self):
1683
+ from neutronclient.common.exceptions import NeutronClientException
1684
+ client = self.neutron()
1686
sec = client.create_security_group({'security_group': {
1687
'name': self.physical_resource_name(),
1688
@@ -46,7 +46,7 @@ class SecurityGroup(resource.Resource):
1689
self.resource_id_set(sec['id'])
1690
if self.properties['SecurityGroupIngress']:
1691
for i in self.properties['SecurityGroupIngress']:
1692
- # Quantum only accepts positive ints
1693
+ # Neutron only accepts positive ints
1694
if int(i['FromPort']) < 0:
1695
i['FromPort'] = None
1696
if int(i['ToPort']) < 0:
1697
@@ -66,7 +66,7 @@ class SecurityGroup(resource.Resource):
1698
'security_group_id': sec['id']
1701
- except QuantumClientException as ex:
1702
+ except NeutronClientException as ex:
1703
if ex.status_code == 409:
1704
# no worries, the rule is already there
1706
@@ -87,7 +87,7 @@ class SecurityGroup(resource.Resource):
1707
'security_group_id': sec['id']
1710
- except QuantumClientException as ex:
1711
+ except NeutronClientException as ex:
1712
if ex.status_code == 409:
1713
# no worries, the rule is already there
1715
@@ -128,8 +128,8 @@ class SecurityGroup(resource.Resource):
1718
def handle_delete(self):
1719
- if self.properties['VpcId'] and clients.quantumclient is not None:
1720
- self._handle_delete_quantum()
1721
+ if self.properties['VpcId'] and clients.neutronclient is not None:
1722
+ self._handle_delete_neutron()
1724
self._handle_delete_nova()
1726
@@ -149,28 +149,28 @@ class SecurityGroup(resource.Resource):
1727
self.nova().security_groups.delete(self.resource_id)
1728
self.resource_id = None
1730
- def _handle_delete_quantum(self):
1731
- from quantumclient.common.exceptions import QuantumClientException
1732
- client = self.quantum()
1733
+ def _handle_delete_neutron(self):
1734
+ from neutronclient.common.exceptions import NeutronClientException
1735
+ client = self.neutron()
1737
if self.resource_id is not None:
1739
sec = client.show_security_group(
1740
self.resource_id)['security_group']
1741
- except QuantumClientException as ex:
1742
+ except NeutronClientException as ex:
1743
if ex.status_code != 404:
1746
for rule in sec['security_group_rules']:
1748
client.delete_security_group_rule(rule['id'])
1749
- except QuantumClientException as ex:
1750
+ except NeutronClientException as ex:
1751
if ex.status_code != 404:
1755
client.delete_security_group(self.resource_id)
1756
- except QuantumClientException as ex:
1757
+ except NeutronClientException as ex:
1758
if ex.status_code != 404:
1760
self.resource_id = None
1761
diff -Naurp heat-2013.2.b2.orig/heat/engine/resources/subnet.py heat-2013.2.b2/heat/engine/resources/subnet.py
1762
--- heat-2013.2.b2.orig/heat/engine/resources/subnet.py 2013-08-07 22:22:07.379156844 +0000
1763
+++ heat-2013.2.b2/heat/engine/resources/subnet.py 2013-08-07 22:24:21.107156844 +0000
1764
@@ -43,7 +43,7 @@ class Subnet(resource.Resource):
1767
def handle_create(self):
1768
- client = self.quantum()
1769
+ client = self.neutron()
1770
# TODO(sbaker) Verify that this CidrBlock is within the vpc CidrBlock
1771
network_id = self.properties.get('VpcId')
1773
@@ -55,7 +55,7 @@ class Subnet(resource.Resource):
1775
subnet = client.create_subnet({'subnet': props})['subnet']
1777
- router = VPC.router_for_vpc(self.quantum(), network_id)
1778
+ router = VPC.router_for_vpc(self.neutron(), network_id)
1780
client.add_interface_router(
1782
@@ -63,25 +63,25 @@ class Subnet(resource.Resource):
1783
self.resource_id_set(subnet['id'])
1785
def handle_delete(self):
1786
- from quantumclient.common.exceptions import QuantumClientException
1787
+ from neutronclient.common.exceptions import NeutronClientException
1789
- client = self.quantum()
1790
+ client = self.neutron()
1791
network_id = self.properties.get('VpcId')
1792
subnet_id = self.resource_id
1795
- router = VPC.router_for_vpc(self.quantum(), network_id)
1796
+ router = VPC.router_for_vpc(self.neutron(), network_id)
1798
client.remove_interface_router(
1800
{'subnet_id': subnet_id})
1801
- except QuantumClientException as ex:
1802
+ except NeutronClientException as ex:
1803
if ex.status_code != 404:
1807
client.delete_subnet(subnet_id)
1808
- except QuantumClientException as ex:
1809
+ except NeutronClientException as ex:
1810
if ex.status_code != 404:
1813
@@ -92,7 +92,7 @@ class Subnet(resource.Resource):
1816
def resource_mapping():
1817
- if clients.quantumclient is None:
1818
+ if clients.neutronclient is None:
1822
diff -Naurp heat-2013.2.b2.orig/heat/engine/resources/vpc.py heat-2013.2.b2/heat/engine/resources/vpc.py
1823
--- heat-2013.2.b2.orig/heat/engine/resources/vpc.py 2013-08-07 22:22:07.379156844 +0000
1824
+++ heat-2013.2.b2/heat/engine/resources/vpc.py 2013-08-07 22:24:21.107156844 +0000
1825
@@ -17,7 +17,7 @@ from heat.common import exception
1826
from heat.engine import clients
1827
from heat.openstack.common import log as logging
1828
from heat.engine import resource
1829
-from heat.engine.resources.quantum import quantum
1830
+from heat.engine.resources.neutron import neutron
1832
logger = logging.getLogger(__name__)
1834
@@ -43,7 +43,7 @@ class VPC(resource.Resource):
1837
def handle_create(self):
1838
- client = self.quantum()
1839
+ client = self.neutron()
1840
# The VPC's net and router are associated by having identical names.
1841
net_props = {'name': self.physical_resource_name()}
1842
router_props = {'name': self.physical_resource_name()}
1843
@@ -59,7 +59,7 @@ class VPC(resource.Resource):
1846
def router_for_vpc(client, network_id):
1847
- # first get the quantum net
1848
+ # first get the neutron net
1849
net = VPC.network_for_vpc(client, network_id)
1850
# then find a router with the same name
1851
routers = client.list_routers(name=net['name'])['routers']
1852
@@ -73,31 +73,31 @@ class VPC(resource.Resource):
1855
def check_create_complete(self, *args):
1856
- net = self.network_for_vpc(self.quantum(), self.resource_id)
1857
- if not quantum.QuantumResource.is_built(net):
1858
+ net = self.network_for_vpc(self.neutron(), self.resource_id)
1859
+ if not neutron.NeutronResource.is_built(net):
1861
- router = self.router_for_vpc(self.quantum(), self.resource_id)
1862
- return quantum.QuantumResource.is_built(router)
1863
+ router = self.router_for_vpc(self.neutron(), self.resource_id)
1864
+ return neutron.NeutronResource.is_built(router)
1866
def handle_delete(self):
1867
- from quantumclient.common.exceptions import QuantumClientException
1868
- client = self.quantum()
1869
+ from neutronclient.common.exceptions import NeutronClientException
1870
+ client = self.neutron()
1871
router = self.router_for_vpc(client, self.resource_id)
1873
client.delete_router(router['id'])
1874
- except QuantumClientException as ex:
1875
+ except NeutronClientException as ex:
1876
if ex.status_code != 404:
1880
client.delete_network(self.resource_id)
1881
- except QuantumClientException as ex:
1882
+ except NeutronClientException as ex:
1883
if ex.status_code != 404:
1887
def resource_mapping():
1888
- if clients.quantumclient is None:
1889
+ if clients.neutronclient is None:
1893
diff -Naurp heat-2013.2.b2.orig/heat/tests/templates/Neutron.template heat-2013.2.b2/heat/tests/templates/Neutron.template
1894
--- heat-2013.2.b2.orig/heat/tests/templates/Neutron.template 1970-01-01 00:00:00.000000000 +0000
1895
+++ heat-2013.2.b2/heat/tests/templates/Neutron.template 2013-08-07 22:24:21.107156844 +0000
1898
+ "AWSTemplateFormatVersion" : "2010-09-09",
1900
+ "Description" : "Template to test Neutron resources",
1908
+ "Type": "OS::Neutron::Net",
1910
+ "name": "the_network"
1913
+ "unnamed_network": {
1914
+ "Type": "OS::Neutron::Net"
1916
+ "admin_down_network": {
1917
+ "Type": "OS::Neutron::Net",
1919
+ "admin_state_up": false
1924
+ "Type": "OS::Neutron::Subnet",
1926
+ "network_id": { "Ref" : "network" },
1928
+ "cidr": "10.0.3.0/24",
1929
+ "allocation_pools": [{"start": "10.0.3.20", "end": "10.0.3.150"}]
1934
+ "Type": "OS::Neutron::Port",
1936
+ "device_id": "d6b4d3a5-c700-476f-b609-1493dd9dadc0",
1938
+ "network_id": { "Ref" : "network" },
1940
+ "subnet_id": { "Ref" : "subnet" },
1941
+ "ip_address": "10.0.3.21"
1947
+ "Type": "OS::Neutron::Router"
1950
+ "router_interface": {
1951
+ "Type": "OS::Neutron::RouterInterface",
1953
+ "router_id": { "Ref" : "router" },
1954
+ "subnet_id": { "Ref" : "subnet" }
1959
+ "the_network_status" : {
1960
+ "Value" : { "Fn::GetAtt" : [ "network", "status" ]},
1961
+ "Description" : "Status of network"
1963
+ "port_device_owner" : {
1964
+ "Value" : { "Fn::GetAtt" : [ "port", "device_owner" ]},
1965
+ "Description" : "Device owner of the port"
1967
+ "port_fixed_ips" : {
1968
+ "Value" : { "Fn::GetAtt" : [ "port", "fixed_ips" ]},
1969
+ "Description" : "Fixed IPs of the port"
1971
+ "port_mac_address" : {
1972
+ "Value" : { "Fn::GetAtt" : [ "port", "mac_address" ]},
1973
+ "Description" : "MAC address of the port"
1976
+ "Value" : { "Fn::GetAtt" : [ "port", "status" ]},
1977
+ "Description" : "Status of the port"
1980
+ "Value" : { "Fn::GetAtt" : [ "port", "show" ]},
1981
+ "Description" : "All attributes for port"
1984
+ "Value" : { "Fn::GetAtt" : [ "subnet", "show" ]},
1985
+ "Description" : "All attributes for subnet"
1987
+ "network_show" : {
1988
+ "Value" : { "Fn::GetAtt" : [ "network", "show" ]},
1989
+ "Description" : "All attributes for network"
1992
+ "Value" : { "Fn::GetAtt" : [ "router", "show" ]},
1993
+ "Description" : "All attributes for router"
1997
diff -Naurp heat-2013.2.b2.orig/heat/tests/templates/Neutron.yaml heat-2013.2.b2/heat/tests/templates/Neutron.yaml
1998
--- heat-2013.2.b2.orig/heat/tests/templates/Neutron.yaml 1970-01-01 00:00:00.000000000 +0000
1999
+++ heat-2013.2.b2/heat/tests/templates/Neutron.yaml 2013-08-07 22:24:21.107156844 +0000
2001
+HeatTemplateFormatVersion: '2012-12-12'
2002
+Description: Template to test Neutron resources
2005
+ Type: OS::Neutron::Net
2006
+ Properties: {name: the_network}
2008
+ Type: 'OS::Neutron::Net'
2009
+ admin_down_network:
2010
+ Type: OS::Neutron::Net
2011
+ Properties: {admin_state_up: false}
2013
+ Type: OS::Neutron::Subnet
2015
+ network_id: {Ref: network}
2019
+ - {end: 10.0.3.150, start: 10.0.3.20}
2021
+ Type: OS::Neutron::Port
2023
+ device_id: d6b4d3a5-c700-476f-b609-1493dd9dadc0
2025
+ network_id: {Ref: network}
2027
+ - subnet_id: {Ref: subnet}
2028
+ ip_address: 10.0.3.21
2030
+ Type: 'OS::Neutron::Router'
2032
+ Type: OS::Neutron::RouterInterface
2034
+ router_id: {Ref: router}
2035
+ subnet_id: {Ref: subnet}
2037
+ the_network_status:
2039
+ Fn::GetAtt: [network, status]
2040
+ Description: Status of network
2041
+ port_device_owner:
2043
+ Fn::GetAtt: [port, device_owner]
2044
+ Description: Device owner of the port
2047
+ Fn::GetAtt: [port, fixed_ips]
2048
+ Description: Fixed IPs of the port
2051
+ Fn::GetAtt: [port, mac_address]
2052
+ Description: MAC address of the port
2055
+ Fn::GetAtt: [port, status]
2056
+ Description: Status of the port
2059
+ Fn::GetAtt: [port, show]
2060
+ Description: All attributes for port
2063
+ Fn::GetAtt: [subnet, show]
2064
+ Description: All attributes for subnet
2067
+ Fn::GetAtt: [network, show]
2068
+ Description: All attributes for network
2071
+ Fn::GetAtt: [router, show]
2072
+ Description: All attributes for router
2073
diff -Naurp heat-2013.2.b2.orig/heat/tests/templates/Quantum.template heat-2013.2.b2/heat/tests/templates/Quantum.template
2074
--- heat-2013.2.b2.orig/heat/tests/templates/Quantum.template 2013-08-07 22:22:07.383156844 +0000
2075
+++ heat-2013.2.b2/heat/tests/templates/Quantum.template 1970-01-01 00:00:00.000000000 +0000
2078
- "AWSTemplateFormatVersion" : "2010-09-09",
2080
- "Description" : "Template to test Quantum resources",
2088
- "Type": "OS::Quantum::Net",
2090
- "name": "the_network"
2093
- "unnamed_network": {
2094
- "Type": "OS::Quantum::Net"
2096
- "admin_down_network": {
2097
- "Type": "OS::Quantum::Net",
2099
- "admin_state_up": false
2104
- "Type": "OS::Quantum::Subnet",
2106
- "network_id": { "Ref" : "network" },
2108
- "cidr": "10.0.3.0/24",
2109
- "allocation_pools": [{"start": "10.0.3.20", "end": "10.0.3.150"}]
2114
- "Type": "OS::Quantum::Port",
2116
- "device_id": "d6b4d3a5-c700-476f-b609-1493dd9dadc0",
2118
- "network_id": { "Ref" : "network" },
2120
- "subnet_id": { "Ref" : "subnet" },
2121
- "ip_address": "10.0.3.21"
2127
- "Type": "OS::Quantum::Router"
2130
- "router_interface": {
2131
- "Type": "OS::Quantum::RouterInterface",
2133
- "router_id": { "Ref" : "router" },
2134
- "subnet_id": { "Ref" : "subnet" }
2139
- "the_network_status" : {
2140
- "Value" : { "Fn::GetAtt" : [ "network", "status" ]},
2141
- "Description" : "Status of network"
2143
- "port_device_owner" : {
2144
- "Value" : { "Fn::GetAtt" : [ "port", "device_owner" ]},
2145
- "Description" : "Device owner of the port"
2147
- "port_fixed_ips" : {
2148
- "Value" : { "Fn::GetAtt" : [ "port", "fixed_ips" ]},
2149
- "Description" : "Fixed IPs of the port"
2151
- "port_mac_address" : {
2152
- "Value" : { "Fn::GetAtt" : [ "port", "mac_address" ]},
2153
- "Description" : "MAC address of the port"
2156
- "Value" : { "Fn::GetAtt" : [ "port", "status" ]},
2157
- "Description" : "Status of the port"
2160
- "Value" : { "Fn::GetAtt" : [ "port", "show" ]},
2161
- "Description" : "All attributes for port"
2164
- "Value" : { "Fn::GetAtt" : [ "subnet", "show" ]},
2165
- "Description" : "All attributes for subnet"
2167
- "network_show" : {
2168
- "Value" : { "Fn::GetAtt" : [ "network", "show" ]},
2169
- "Description" : "All attributes for network"
2172
- "Value" : { "Fn::GetAtt" : [ "router", "show" ]},
2173
- "Description" : "All attributes for router"
2177
\ No newline at end of file
2178
diff -Naurp heat-2013.2.b2.orig/heat/tests/templates/Quantum.yaml heat-2013.2.b2/heat/tests/templates/Quantum.yaml
2179
--- heat-2013.2.b2.orig/heat/tests/templates/Quantum.yaml 2013-08-07 22:22:07.383156844 +0000
2180
+++ heat-2013.2.b2/heat/tests/templates/Quantum.yaml 1970-01-01 00:00:00.000000000 +0000
2182
-HeatTemplateFormatVersion: '2012-12-12'
2183
-Description: Template to test Quantum resources
2186
- Type: OS::Quantum::Net
2187
- Properties: {name: the_network}
2189
- Type: 'OS::Quantum::Net'
2190
- admin_down_network:
2191
- Type: OS::Quantum::Net
2192
- Properties: {admin_state_up: false}
2194
- Type: OS::Quantum::Subnet
2196
- network_id: {Ref: network}
2200
- - {end: 10.0.3.150, start: 10.0.3.20}
2202
- Type: OS::Quantum::Port
2204
- device_id: d6b4d3a5-c700-476f-b609-1493dd9dadc0
2206
- network_id: {Ref: network}
2208
- - subnet_id: {Ref: subnet}
2209
- ip_address: 10.0.3.21
2211
- Type: 'OS::Quantum::Router'
2213
- Type: OS::Quantum::RouterInterface
2215
- router_id: {Ref: router}
2216
- subnet_id: {Ref: subnet}
2218
- the_network_status:
2220
- Fn::GetAtt: [network, status]
2221
- Description: Status of network
2222
- port_device_owner:
2224
- Fn::GetAtt: [port, device_owner]
2225
- Description: Device owner of the port
2228
- Fn::GetAtt: [port, fixed_ips]
2229
- Description: Fixed IPs of the port
2232
- Fn::GetAtt: [port, mac_address]
2233
- Description: MAC address of the port
2236
- Fn::GetAtt: [port, status]
2237
- Description: Status of the port
2240
- Fn::GetAtt: [port, show]
2241
- Description: All attributes for port
2244
- Fn::GetAtt: [subnet, show]
2245
- Description: All attributes for subnet
2248
- Fn::GetAtt: [network, show]
2249
- Description: All attributes for network
2252
- Fn::GetAtt: [router, show]
2253
- Description: All attributes for router
2254
diff -Naurp heat-2013.2.b2.orig/heat/tests/test_instance_network.py heat-2013.2.b2/heat/tests/test_instance_network.py
2255
--- heat-2013.2.b2.orig/heat/tests/test_instance_network.py 2013-08-07 22:22:07.383156844 +0000
2256
+++ heat-2013.2.b2/heat/tests/test_instance_network.py 2013-08-07 22:24:21.107156844 +0000
2257
@@ -109,7 +109,7 @@ wp_template_with_nic = '''
2261
-class FakeQuantum(object):
2262
+class FakeNeutron(object):
2264
def show_subnet(self, subnet, **_params):
2266
@@ -168,8 +168,8 @@ class instancesTest(HeatTestCase):
2267
self.m.StubOutWithMock(instance, 'nova')
2268
instance.nova().MultipleTimes().AndReturn(self.fc)
2270
- self.m.StubOutWithMock(instance, 'quantum')
2271
- instance.quantum().MultipleTimes().AndReturn(FakeQuantum())
2272
+ self.m.StubOutWithMock(instance, 'neutron')
2273
+ instance.neutron().MultipleTimes().AndReturn(FakeNeutron())
2275
instance.t = instance.stack.resolve_runtime_data(instance.t)
2277
@@ -211,8 +211,8 @@ class instancesTest(HeatTestCase):
2278
instance = instances.Instance('%s_name' % name,
2279
t['Resources']['WebServer'], stack)
2281
- self.m.StubOutWithMock(nic, 'quantum')
2282
- nic.quantum().MultipleTimes().AndReturn(FakeQuantum())
2283
+ self.m.StubOutWithMock(nic, 'neutron')
2284
+ nic.neutron().MultipleTimes().AndReturn(FakeNeutron())
2286
self.m.StubOutWithMock(instance, 'nova')
2287
instance.nova().MultipleTimes().AndReturn(self.fc)
2288
diff -Naurp heat-2013.2.b2.orig/heat/tests/test_neutron.py heat-2013.2.b2/heat/tests/test_neutron.py
2289
--- heat-2013.2.b2.orig/heat/tests/test_neutron.py 1970-01-01 00:00:00.000000000 +0000
2290
+++ heat-2013.2.b2/heat/tests/test_neutron.py 2013-08-07 22:24:21.107156844 +0000
2292
+# vim: tabstop=4 shiftwidth=4 softtabstop=4
2294
+# Licensed under the Apache License, Version 2.0 (the "License"); you may
2295
+# not use this file except in compliance with the License. You may obtain
2296
+# a copy of the License at
2298
+# http://www.apache.org/licenses/LICENSE-2.0
2300
+# Unless required by applicable law or agreed to in writing, software
2301
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
2302
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
2303
+# License for the specific language governing permissions and limitations
2304
+# under the License.
2307
+from testtools import skipIf
2309
+from heat.engine import clients
2310
+from heat.common import exception
2311
+from heat.common import template_format
2312
+from heat.engine import properties
2313
+from heat.engine import resource
2314
+from heat.engine import scheduler
2315
+from heat.engine.resources.neutron import net
2316
+from heat.engine.resources.neutron import subnet
2317
+from heat.engine.resources.neutron import router
2318
+from heat.engine.resources.neutron.neutron import NeutronResource as qr
2319
+from heat.openstack.common.importutils import try_import
2320
+from heat.tests.common import HeatTestCase
2321
+from heat.tests import fakes
2322
+from heat.tests import utils
2323
+from heat.tests.utils import setup_dummy_db
2324
+from heat.tests.utils import parse_stack
2326
+neutronclient = try_import('neutronclient.v2_0.client')
2327
+qe = try_import('neutronclient.common.exceptions')
2329
+neutron_template = '''
2331
+ "AWSTemplateFormatVersion" : "2010-09-09",
2332
+ "Description" : "Template to test Neutron resources",
2333
+ "Parameters" : {},
2336
+ "Type": "OS::Neutron::Net",
2338
+ "name": "the_network"
2341
+ "unnamed_network": {
2342
+ "Type": "OS::Neutron::Net"
2344
+ "admin_down_network": {
2345
+ "Type": "OS::Neutron::Net",
2347
+ "admin_state_up": false
2351
+ "Type": "OS::Neutron::Subnet",
2353
+ "network_id": { "Ref" : "network" },
2355
+ "cidr": "10.0.3.0/24",
2356
+ "allocation_pools": [{"start": "10.0.3.20", "end": "10.0.3.150"}],
2357
+ "dns_nameservers": ["8.8.8.8"]
2361
+ "Type": "OS::Neutron::Port",
2363
+ "device_id": "d6b4d3a5-c700-476f-b609-1493dd9dadc0",
2365
+ "network_id": { "Ref" : "network" },
2367
+ "subnet_id": { "Ref" : "subnet" },
2368
+ "ip_address": "10.0.3.21"
2373
+ "Type": "OS::Neutron::Port",
2376
+ "network_id": { "Ref" : "network" }
2380
+ "Type": "OS::Neutron::Router"
2382
+ "router_interface": {
2383
+ "Type": "OS::Neutron::RouterInterface",
2385
+ "router_id": { "Ref" : "router" },
2386
+ "subnet_id": { "Ref" : "subnet" }
2390
+ "Type": "OS::Neutron::RouterGateway",
2392
+ "router_id": { "Ref" : "router" },
2393
+ "network_id": { "Ref" : "network" }
2400
+neutron_floating_template = '''
2402
+ "AWSTemplateFormatVersion" : "2010-09-09",
2403
+ "Description" : "Template to test Neutron resources",
2404
+ "Parameters" : {},
2406
+ "port_floating": {
2407
+ "Type": "OS::Neutron::Port",
2409
+ "network_id": "xyz1234",
2411
+ "subnet_id": "12.12.12.0",
2412
+ "ip_address": "10.0.0.10"
2417
+ "Type": "OS::Neutron::FloatingIP",
2419
+ "floating_network_id": "abcd1234",
2422
+ "floating_ip_assoc": {
2423
+ "Type": "OS::Neutron::FloatingIPAssociation",
2425
+ "floatingip_id": { "Ref" : "floating_ip" },
2426
+ "port_id": { "Ref" : "port_floating" }
2430
+ "Type": "OS::Neutron::Router"
2433
+ "Type": "OS::Neutron::RouterGateway",
2435
+ "router_id": { "Ref" : "router" },
2436
+ "network_id": "abcd1234"
2444
+class NeutronTest(HeatTestCase):
2446
+ def test_validate_properties(self):
2447
+ vs = {'router:external': True}
2448
+ data = {'admin_state_up': False,
2449
+ 'value_specs': vs}
2450
+ p = properties.Properties(net.Net.properties_schema, data)
2451
+ self.assertEqual(None, qr.validate_properties(p))
2453
+ vs['shared'] = True
2454
+ self.assertEqual('shared not allowed in value_specs',
2455
+ qr.validate_properties(p))
2458
+ vs['name'] = 'foo'
2459
+ self.assertEqual('name not allowed in value_specs',
2460
+ qr.validate_properties(p))
2463
+ vs['tenant_id'] = '1234'
2464
+ self.assertEqual('tenant_id not allowed in value_specs',
2465
+ qr.validate_properties(p))
2466
+ vs.pop('tenant_id')
2468
+ vs['foo'] = '1234'
2469
+ self.assertEqual(None, qr.validate_properties(p))
2471
+ def test_prepare_properties(self):
2472
+ data = {'admin_state_up': False,
2473
+ 'value_specs': {'router:external': True}}
2474
+ p = properties.Properties(net.Net.properties_schema, data)
2475
+ props = qr.prepare_properties(p, 'resource_name')
2476
+ self.assertEqual({'name': 'resource_name',
2477
+ 'router:external': True,
2478
+ 'admin_state_up': False}, props)
2480
+ def test_is_built(self):
2481
+ self.assertTrue(qr.is_built({
2482
+ 'name': 'the_net',
2483
+ 'status': 'ACTIVE'
2485
+ self.assertTrue(qr.is_built({
2486
+ 'name': 'the_net',
2489
+ self.assertFalse(qr.is_built({
2490
+ 'name': 'the_net',
2493
+ self.assertRaises(exception.Error, qr.is_built, {
2494
+ 'name': 'the_net',
2495
+ 'status': 'FROBULATING'
2499
+@skipIf(neutronclient is None, 'neutronclient unavailable')
2500
+class NeutronNetTest(HeatTestCase):
2503
+ super(NeutronNetTest, self).setUp()
2504
+ self.m.StubOutWithMock(neutronclient.Client, 'create_network')
2505
+ self.m.StubOutWithMock(neutronclient.Client, 'delete_network')
2506
+ self.m.StubOutWithMock(neutronclient.Client, 'show_network')
2507
+ self.m.StubOutWithMock(clients.OpenStackClients, 'keystone')
2510
+ def create_net(self, t, stack, resource_name):
2511
+ rsrc = net.Net('test_net', t['Resources'][resource_name], stack)
2512
+ scheduler.TaskRunner(rsrc.create)()
2513
+ self.assertEqual((rsrc.CREATE, rsrc.COMPLETE), rsrc.state)
2516
+ def test_net(self):
2517
+ clients.OpenStackClients.keystone().AndReturn(
2518
+ fakes.FakeKeystoneClient())
2519
+ neutronclient.Client.create_network({
2520
+ 'network': {'name': u'the_network', 'admin_state_up': True}
2521
+ }).AndReturn({"network": {
2522
+ "status": "BUILD",
2525
+ "admin_state_up": False,
2527
+ "tenant_id": "c1210485b2424d48804aad5d39c61b8f",
2528
+ "id": "fc68ea2c-b60b-4b4f-bd82-94ec81110766"
2531
+ neutronclient.Client.show_network(
2532
+ 'fc68ea2c-b60b-4b4f-bd82-94ec81110766'
2533
+ ).AndReturn({"network": {
2534
+ "status": "BUILD",
2537
+ "admin_state_up": False,
2539
+ "tenant_id": "c1210485b2424d48804aad5d39c61b8f",
2540
+ "id": "fc68ea2c-b60b-4b4f-bd82-94ec81110766"
2543
+ neutronclient.Client.show_network(
2544
+ 'fc68ea2c-b60b-4b4f-bd82-94ec81110766'
2545
+ ).AndReturn({"network": {
2546
+ "status": "ACTIVE",
2549
+ "admin_state_up": False,
2551
+ "tenant_id": "c1210485b2424d48804aad5d39c61b8f",
2552
+ "id": "fc68ea2c-b60b-4b4f-bd82-94ec81110766"
2555
+ neutronclient.Client.show_network(
2556
+ 'fc68ea2c-b60b-4b4f-bd82-94ec81110766'
2557
+ ).AndRaise(qe.NeutronClientException(status_code=404))
2559
+ neutronclient.Client.show_network(
2560
+ 'fc68ea2c-b60b-4b4f-bd82-94ec81110766'
2561
+ ).AndReturn({"network": {
2562
+ "status": "ACTIVE",
2565
+ "admin_state_up": False,
2567
+ "tenant_id": "c1210485b2424d48804aad5d39c61b8f",
2568
+ "id": "fc68ea2c-b60b-4b4f-bd82-94ec81110766"
2571
+ neutronclient.Client.show_network(
2572
+ 'fc68ea2c-b60b-4b4f-bd82-94ec81110766'
2573
+ ).AndReturn({"network": {
2574
+ "status": "ACTIVE",
2577
+ "admin_state_up": False,
2579
+ "tenant_id": "c1210485b2424d48804aad5d39c61b8f",
2580
+ "id": "fc68ea2c-b60b-4b4f-bd82-94ec81110766"
2583
+ neutronclient.Client.delete_network(
2584
+ 'fc68ea2c-b60b-4b4f-bd82-94ec81110766'
2587
+ neutronclient.Client.show_network(
2588
+ 'fc68ea2c-b60b-4b4f-bd82-94ec81110766'
2589
+ ).AndRaise(qe.NeutronClientException(status_code=404))
2591
+ neutronclient.Client.delete_network(
2592
+ 'fc68ea2c-b60b-4b4f-bd82-94ec81110766'
2593
+ ).AndRaise(qe.NeutronClientException(status_code=404))
2595
+ self.m.ReplayAll()
2596
+ t = template_format.parse(neutron_template)
2597
+ stack = parse_stack(t)
2598
+ rsrc = self.create_net(t, stack, 'network')
2600
+ # assert the implicit dependency between the gateway and the interface
2601
+ deps = stack.dependencies[stack['router_interface']]
2602
+ self.assertIn(stack['gateway'], deps)
2604
+ # assert the implicit dependency between the gateway and the subnet
2605
+ deps = stack.dependencies[stack['subnet']]
2606
+ self.assertIn(stack['gateway'], deps)
2610
+ ref_id = rsrc.FnGetRefId()
2611
+ self.assertEqual('fc68ea2c-b60b-4b4f-bd82-94ec81110766', ref_id)
2613
+ self.assertEqual(None, rsrc.FnGetAtt('status'))
2614
+ self.assertEqual('ACTIVE', rsrc.FnGetAtt('status'))
2616
+ rsrc.FnGetAtt('Foo')
2617
+ raise Exception('Expected InvalidTemplateAttribute')
2618
+ except exception.InvalidTemplateAttribute:
2621
+ self.assertEqual('fc68ea2c-b60b-4b4f-bd82-94ec81110766',
2622
+ rsrc.FnGetAtt('id'))
2624
+ self.assertRaises(resource.UpdateReplace,
2625
+ rsrc.handle_update, {}, {}, {})
2627
+ scheduler.TaskRunner(rsrc.delete)()
2628
+ rsrc.state_set(rsrc.CREATE, rsrc.COMPLETE, 'to delete again')
2629
+ scheduler.TaskRunner(rsrc.delete)()
2630
+ self.m.VerifyAll()
2633
+@skipIf(neutronclient is None, 'neutronclient unavailable')
2634
+class NeutronSubnetTest(HeatTestCase):
2637
+ super(NeutronSubnetTest, self).setUp()
2638
+ self.m.StubOutWithMock(neutronclient.Client, 'create_subnet')
2639
+ self.m.StubOutWithMock(neutronclient.Client, 'delete_subnet')
2640
+ self.m.StubOutWithMock(neutronclient.Client, 'show_subnet')
2641
+ self.m.StubOutWithMock(clients.OpenStackClients, 'keystone')
2644
+ def create_subnet(self, t, stack, resource_name):
2645
+ rsrc = subnet.Subnet('test_subnet', t['Resources'][resource_name],
2647
+ scheduler.TaskRunner(rsrc.create)()
2648
+ self.assertEqual((rsrc.CREATE, rsrc.COMPLETE), rsrc.state)
2651
+ def test_subnet(self):
2653
+ clients.OpenStackClients.keystone().AndReturn(
2654
+ fakes.FakeKeystoneClient())
2655
+ neutronclient.Client.create_subnet({
2657
+ 'name': utils.PhysName('test_stack', 'test_subnet'),
2658
+ 'network_id': u'None',
2659
+ 'dns_nameservers': [u'8.8.8.8'],
2660
+ 'allocation_pools': [
2661
+ {'start': u'10.0.3.20', 'end': u'10.0.3.150'}],
2663
+ 'cidr': u'10.0.3.0/24'
2667
+ "allocation_pools": [
2668
+ {"start": "10.0.3.20", "end": "10.0.3.150"}],
2669
+ "cidr": "10.0.3.0/24",
2670
+ "dns_nameservers": ["8.8.8.8"],
2671
+ "enable_dhcp": True,
2672
+ "gateway_ip": "10.0.3.1",
2673
+ "id": "91e47a57-7508-46fe-afc9-fc454e8580e1",
2676
+ "network_id": "fc68ea2c-b60b-4b4f-bd82-94ec81110766",
2677
+ "tenant_id": "c1210485b2424d48804aad5d39c61b8f"
2680
+ neutronclient.Client.show_subnet(
2681
+ '91e47a57-7508-46fe-afc9-fc454e8580e1').AndRaise(
2682
+ qe.NeutronClientException(status_code=404))
2686
+ "network_id": "fc68ea2c-b60b-4b4f-bd82-94ec81110766",
2687
+ "tenant_id": "c1210485b2424d48804aad5d39c61b8f",
2688
+ "allocation_pools": [
2689
+ {"start": "10.0.3.20", "end": "10.0.3.150"}],
2690
+ "gateway_ip": "10.0.3.1",
2692
+ "cidr": "10.0.3.0/24",
2693
+ "dns_nameservers": ["8.8.8.8"],
2694
+ "id": "91e47a57-7508-46fe-afc9-fc454e8580e1",
2695
+ "enable_dhcp": True,
2698
+ neutronclient.Client.show_subnet(
2699
+ '91e47a57-7508-46fe-afc9-fc454e8580e1').AndReturn(sn)
2700
+ neutronclient.Client.show_subnet(
2701
+ '91e47a57-7508-46fe-afc9-fc454e8580e1').AndReturn(sn)
2702
+ neutronclient.Client.show_subnet(
2703
+ '91e47a57-7508-46fe-afc9-fc454e8580e1').AndReturn(sn)
2705
+ neutronclient.Client.delete_subnet(
2706
+ '91e47a57-7508-46fe-afc9-fc454e8580e1'
2709
+ neutronclient.Client.show_subnet(
2710
+ '91e47a57-7508-46fe-afc9-fc454e8580e1'
2711
+ ).AndRaise(qe.NeutronClientException(status_code=404))
2713
+ neutronclient.Client.delete_subnet(
2714
+ '91e47a57-7508-46fe-afc9-fc454e8580e1'
2715
+ ).AndRaise(qe.NeutronClientException(status_code=404))
2717
+ self.m.ReplayAll()
2718
+ t = template_format.parse(neutron_template)
2719
+ stack = parse_stack(t)
2720
+ rsrc = self.create_subnet(t, stack, 'subnet')
2724
+ ref_id = rsrc.FnGetRefId()
2725
+ self.assertEqual('91e47a57-7508-46fe-afc9-fc454e8580e1', ref_id)
2726
+ self.assertEqual(None,
2727
+ rsrc.FnGetAtt('network_id'))
2728
+ self.assertEqual('fc68ea2c-b60b-4b4f-bd82-94ec81110766',
2729
+ rsrc.FnGetAtt('network_id'))
2730
+ self.assertEqual('8.8.8.8', rsrc.FnGetAtt('dns_nameservers')[0])
2731
+ self.assertEqual('91e47a57-7508-46fe-afc9-fc454e8580e1',
2732
+ rsrc.FnGetAtt('id'))
2734
+ # assert the dependency (implicit or explicit) between the ports
2736
+ self.assertIn(stack['port'], stack.dependencies[stack['subnet']])
2737
+ self.assertIn(stack['port2'], stack.dependencies[stack['subnet']])
2739
+ self.assertRaises(resource.UpdateReplace,
2740
+ rsrc.handle_update, {}, {}, {})
2742
+ self.assertEqual(scheduler.TaskRunner(rsrc.delete)(), None)
2743
+ rsrc.state_set(rsrc.CREATE, rsrc.COMPLETE, 'to delete again')
2744
+ self.assertEqual(scheduler.TaskRunner(rsrc.delete)(), None)
2745
+ self.m.VerifyAll()
2747
+ def test_subnet_disable_dhcp(self):
2749
+ clients.OpenStackClients.keystone().AndReturn(
2750
+ fakes.FakeKeystoneClient())
2751
+ neutronclient.Client.create_subnet({
2753
+ 'name': utils.PhysName('test_stack', 'test_subnet'),
2754
+ 'network_id': u'None',
2755
+ 'dns_nameservers': [u'8.8.8.8'],
2756
+ 'allocation_pools': [
2757
+ {'start': u'10.0.3.20', 'end': u'10.0.3.150'}],
2759
+ 'enable_dhcp': False,
2760
+ 'cidr': u'10.0.3.0/24'
2764
+ "allocation_pools": [
2765
+ {"start": "10.0.3.20", "end": "10.0.3.150"}],
2766
+ "cidr": "10.0.3.0/24",
2767
+ "dns_nameservers": ["8.8.8.8"],
2768
+ "enable_dhcp": False,
2769
+ "gateway_ip": "10.0.3.1",
2770
+ "id": "91e47a57-7508-46fe-afc9-fc454e8580e1",
2773
+ "network_id": "fc68ea2c-b60b-4b4f-bd82-94ec81110766",
2774
+ "tenant_id": "c1210485b2424d48804aad5d39c61b8f"
2778
+ neutronclient.Client.show_subnet(
2779
+ '91e47a57-7508-46fe-afc9-fc454e8580e1').AndReturn({
2782
+ "network_id": "fc68ea2c-b60b-4b4f-bd82-94ec81110766",
2783
+ "tenant_id": "c1210485b2424d48804aad5d39c61b8f",
2784
+ "allocation_pools": [
2785
+ {"start": "10.0.3.20", "end": "10.0.3.150"}],
2786
+ "gateway_ip": "10.0.3.1",
2788
+ "cidr": "10.0.3.0/24",
2789
+ "dns_nameservers": ["8.8.8.8"],
2790
+ "id": "91e47a57-7508-46fe-afc9-fc454e8580e1",
2791
+ "enable_dhcp": False,
2795
+ neutronclient.Client.delete_subnet(
2796
+ '91e47a57-7508-46fe-afc9-fc454e8580e1'
2799
+ neutronclient.Client.show_subnet(
2800
+ '91e47a57-7508-46fe-afc9-fc454e8580e1'
2801
+ ).AndRaise(qe.NeutronClientException(status_code=404))
2803
+ self.m.ReplayAll()
2804
+ t = template_format.parse(neutron_template)
2805
+ t['Resources']['subnet']['Properties']['enable_dhcp'] = 'False'
2806
+ stack = parse_stack(t)
2807
+ rsrc = self.create_subnet(t, stack, 'subnet')
2811
+ ref_id = rsrc.FnGetRefId()
2812
+ self.assertEqual('91e47a57-7508-46fe-afc9-fc454e8580e1', ref_id)
2813
+ self.assertEqual(False, rsrc.FnGetAtt('enable_dhcp'))
2814
+ self.assertEqual(rsrc.delete(), None)
2815
+ self.m.VerifyAll()
2818
+@skipIf(neutronclient is None, 'neutronclient unavailable')
2819
+class NeutronRouterTest(HeatTestCase):
2821
+ super(NeutronRouterTest, self).setUp()
2822
+ self.m.StubOutWithMock(neutronclient.Client, 'create_router')
2823
+ self.m.StubOutWithMock(neutronclient.Client, 'delete_router')
2824
+ self.m.StubOutWithMock(neutronclient.Client, 'show_router')
2825
+ self.m.StubOutWithMock(neutronclient.Client, 'add_interface_router')
2826
+ self.m.StubOutWithMock(neutronclient.Client, 'remove_interface_router')
2827
+ self.m.StubOutWithMock(neutronclient.Client, 'add_gateway_router')
2828
+ self.m.StubOutWithMock(neutronclient.Client, 'remove_gateway_router')
2829
+ self.m.StubOutWithMock(clients.OpenStackClients, 'keystone')
2832
+ def create_router(self, t, stack, resource_name):
2833
+ rsrc = router.Router('router', t['Resources'][resource_name], stack)
2834
+ scheduler.TaskRunner(rsrc.create)()
2835
+ self.assertEqual((rsrc.CREATE, rsrc.COMPLETE), rsrc.state)
2838
+ def create_router_interface(self, t, stack, resource_name, properties={}):
2839
+ t['Resources'][resource_name]['Properties'] = properties
2840
+ rsrc = router.RouterInterface(
2841
+ 'router_interface',
2842
+ t['Resources'][resource_name],
2844
+ scheduler.TaskRunner(rsrc.create)()
2845
+ self.assertEqual((rsrc.CREATE, rsrc.COMPLETE), rsrc.state)
2848
+ def create_gateway_router(self, t, stack, resource_name, properties={}):
2849
+ t['Resources'][resource_name]['Properties'] = properties
2850
+ rsrc = router.RouterGateway(
2852
+ t['Resources'][resource_name],
2854
+ scheduler.TaskRunner(rsrc.create)()
2855
+ self.assertEqual((rsrc.CREATE, rsrc.COMPLETE), rsrc.state)
2858
+ def test_router(self):
2859
+ clients.OpenStackClients.keystone().AndReturn(
2860
+ fakes.FakeKeystoneClient())
2861
+ neutronclient.Client.create_router({
2863
+ 'name': utils.PhysName('test_stack', 'router'),
2864
+ 'admin_state_up': True,
2868
+ "status": "BUILD",
2869
+ "external_gateway_info": None,
2870
+ "name": utils.PhysName('test_stack', 'router'),
2871
+ "admin_state_up": True,
2872
+ "tenant_id": "3e21026f2dc94372b105808c0e721661",
2873
+ "id": "3e46229d-8fce-4733-819a-b5fe630550f8"
2876
+ neutronclient.Client.show_router(
2877
+ '3e46229d-8fce-4733-819a-b5fe630550f8').AndReturn({
2879
+ "status": "BUILD",
2880
+ "external_gateway_info": None,
2881
+ "name": utils.PhysName('test_stack', 'router'),
2882
+ "admin_state_up": True,
2883
+ "tenant_id": "3e21026f2dc94372b105808c0e721661",
2885
+ "id": "3e46229d-8fce-4733-819a-b5fe630550f8"
2888
+ neutronclient.Client.show_router(
2889
+ '3e46229d-8fce-4733-819a-b5fe630550f8').AndReturn({
2891
+ "status": "ACTIVE",
2892
+ "external_gateway_info": None,
2893
+ "name": utils.PhysName('test_stack', 'router'),
2894
+ "admin_state_up": True,
2895
+ "tenant_id": "3e21026f2dc94372b105808c0e721661",
2897
+ "id": "3e46229d-8fce-4733-819a-b5fe630550f8"
2901
+ neutronclient.Client.show_router(
2902
+ '3e46229d-8fce-4733-819a-b5fe630550f8').AndRaise(
2903
+ qe.NeutronClientException(status_code=404))
2904
+ neutronclient.Client.show_router(
2905
+ '3e46229d-8fce-4733-819a-b5fe630550f8').AndReturn({
2907
+ "status": "ACTIVE",
2908
+ "external_gateway_info": None,
2909
+ "name": utils.PhysName('test_stack', 'router'),
2910
+ "admin_state_up": True,
2911
+ "tenant_id": "3e21026f2dc94372b105808c0e721661",
2913
+ "id": "3e46229d-8fce-4733-819a-b5fe630550f8"
2916
+ neutronclient.Client.show_router(
2917
+ '3e46229d-8fce-4733-819a-b5fe630550f8').AndReturn({
2919
+ "status": "ACTIVE",
2920
+ "external_gateway_info": None,
2921
+ "name": utils.PhysName('test_stack', 'router'),
2922
+ "admin_state_up": True,
2923
+ "tenant_id": "3e21026f2dc94372b105808c0e721661",
2925
+ "id": "3e46229d-8fce-4733-819a-b5fe630550f8"
2929
+ neutronclient.Client.delete_router(
2930
+ '3e46229d-8fce-4733-819a-b5fe630550f8'
2933
+ neutronclient.Client.show_router(
2934
+ '3e46229d-8fce-4733-819a-b5fe630550f8'
2935
+ ).AndRaise(qe.NeutronClientException(status_code=404))
2937
+ neutronclient.Client.delete_router(
2938
+ '3e46229d-8fce-4733-819a-b5fe630550f8'
2939
+ ).AndRaise(qe.NeutronClientException(status_code=404))
2941
+ self.m.ReplayAll()
2942
+ t = template_format.parse(neutron_template)
2943
+ stack = parse_stack(t)
2944
+ rsrc = self.create_router(t, stack, 'router')
2948
+ ref_id = rsrc.FnGetRefId()
2949
+ self.assertEqual('3e46229d-8fce-4733-819a-b5fe630550f8', ref_id)
2950
+ self.assertEqual(None,
2951
+ rsrc.FnGetAtt('tenant_id'))
2952
+ self.assertEqual('3e21026f2dc94372b105808c0e721661',
2953
+ rsrc.FnGetAtt('tenant_id'))
2954
+ self.assertEqual('3e46229d-8fce-4733-819a-b5fe630550f8',
2955
+ rsrc.FnGetAtt('id'))
2957
+ self.assertRaises(resource.UpdateReplace,
2958
+ rsrc.handle_update, {}, {}, {})
2960
+ self.assertEqual(scheduler.TaskRunner(rsrc.delete)(), None)
2961
+ rsrc.state_set(rsrc.CREATE, rsrc.COMPLETE, 'to delete again')
2962
+ self.assertEqual(scheduler.TaskRunner(rsrc.delete)(), None)
2963
+ self.m.VerifyAll()
2965
+ def test_router_interface(self):
2966
+ clients.OpenStackClients.keystone().AndReturn(
2967
+ fakes.FakeKeystoneClient())
2968
+ neutronclient.Client.add_interface_router(
2969
+ '3e46229d-8fce-4733-819a-b5fe630550f8',
2970
+ {'subnet_id': '91e47a57-7508-46fe-afc9-fc454e8580e1'}
2972
+ neutronclient.Client.remove_interface_router(
2973
+ '3e46229d-8fce-4733-819a-b5fe630550f8',
2974
+ {'subnet_id': '91e47a57-7508-46fe-afc9-fc454e8580e1'}
2976
+ neutronclient.Client.remove_interface_router(
2977
+ '3e46229d-8fce-4733-819a-b5fe630550f8',
2978
+ {'subnet_id': '91e47a57-7508-46fe-afc9-fc454e8580e1'}
2979
+ ).AndRaise(qe.NeutronClientException(status_code=404))
2980
+ self.m.ReplayAll()
2981
+ t = template_format.parse(neutron_template)
2982
+ stack = parse_stack(t)
2984
+ rsrc = self.create_router_interface(
2985
+ t, stack, 'router_interface', properties={
2986
+ 'router_id': '3e46229d-8fce-4733-819a-b5fe630550f8',
2987
+ 'subnet_id': '91e47a57-7508-46fe-afc9-fc454e8580e1'
2990
+ self.assertEqual(rsrc.delete(), None)
2991
+ rsrc.state_set(rsrc.CREATE, rsrc.COMPLETE, 'to delete again')
2992
+ self.assertEqual(rsrc.delete(), None)
2993
+ self.m.VerifyAll()
2995
+ def test_gateway_router(self):
2996
+ clients.OpenStackClients.keystone().AndReturn(
2997
+ fakes.FakeKeystoneClient())
2998
+ neutronclient.Client.add_gateway_router(
2999
+ '3e46229d-8fce-4733-819a-b5fe630550f8',
3000
+ {'network_id': 'fc68ea2c-b60b-4b4f-bd82-94ec81110766'}
3002
+ neutronclient.Client.remove_gateway_router(
3003
+ '3e46229d-8fce-4733-819a-b5fe630550f8'
3005
+ neutronclient.Client.remove_gateway_router(
3006
+ '3e46229d-8fce-4733-819a-b5fe630550f8'
3007
+ ).AndRaise(qe.NeutronClientException(status_code=404))
3008
+ self.m.ReplayAll()
3009
+ t = template_format.parse(neutron_template)
3010
+ stack = parse_stack(t)
3012
+ rsrc = self.create_gateway_router(
3013
+ t, stack, 'gateway', properties={
3014
+ 'router_id': '3e46229d-8fce-4733-819a-b5fe630550f8',
3015
+ 'network_id': 'fc68ea2c-b60b-4b4f-bd82-94ec81110766'
3018
+ self.assertEqual(rsrc.delete(), None)
3019
+ rsrc.state_set(rsrc.CREATE, rsrc.COMPLETE, 'to delete again')
3020
+ self.assertEqual(rsrc.delete(), None)
3021
+ self.m.VerifyAll()
3024
+@skipIf(neutronclient is None, 'neutronclient unavailable')
3025
+class NeutronFloatingIPTest(HeatTestCase):
3026
+ @skipIf(net.clients.neutronclient is None, "Missing Neutron Client")
3028
+ super(NeutronFloatingIPTest, self).setUp()
3029
+ self.m.StubOutWithMock(neutronclient.Client, 'create_floatingip')
3030
+ self.m.StubOutWithMock(neutronclient.Client, 'delete_floatingip')
3031
+ self.m.StubOutWithMock(neutronclient.Client, 'show_floatingip')
3032
+ self.m.StubOutWithMock(neutronclient.Client, 'update_floatingip')
3033
+ self.m.StubOutWithMock(neutronclient.Client, 'create_port')
3034
+ self.m.StubOutWithMock(neutronclient.Client, 'delete_port')
3035
+ self.m.StubOutWithMock(neutronclient.Client, 'show_port')
3036
+ self.m.StubOutWithMock(clients.OpenStackClients, 'keystone')
3039
+ def test_floating_ip(self):
3041
+ clients.OpenStackClients.keystone().AndReturn(
3042
+ fakes.FakeKeystoneClient())
3043
+ neutronclient.Client.create_floatingip({
3044
+ 'floatingip': {'floating_network_id': u'abcd1234'}
3045
+ }).AndReturn({'floatingip': {
3046
+ "status": "ACTIVE",
3047
+ "id": "fc68ea2c-b60b-4b4f-bd82-94ec81110766"
3050
+ neutronclient.Client.show_floatingip(
3051
+ 'fc68ea2c-b60b-4b4f-bd82-94ec81110766'
3052
+ ).AndRaise(qe.NeutronClientException(status_code=404))
3053
+ neutronclient.Client.show_floatingip(
3054
+ 'fc68ea2c-b60b-4b4f-bd82-94ec81110766'
3055
+ ).MultipleTimes().AndReturn({'floatingip': {
3056
+ "status": "ACTIVE",
3057
+ "id": "fc68ea2c-b60b-4b4f-bd82-94ec81110766"
3060
+ neutronclient.Client.delete_floatingip(
3061
+ 'fc68ea2c-b60b-4b4f-bd82-94ec81110766').AndReturn(None)
3062
+ neutronclient.Client.delete_floatingip(
3063
+ 'fc68ea2c-b60b-4b4f-bd82-94ec81110766').AndRaise(
3064
+ qe.NeutronClientException(status_code=404))
3065
+ self.m.ReplayAll()
3067
+ t = template_format.parse(neutron_floating_template)
3068
+ stack = parse_stack(t)
3070
+ # assert the implicit dependency between the floating_ip
3072
+ deps = stack.dependencies[stack['gateway']]
3073
+ self.assertIn(stack['floating_ip'], deps)
3075
+ fip = stack['floating_ip']
3076
+ scheduler.TaskRunner(fip.create)()
3077
+ self.assertEqual((fip.CREATE, fip.COMPLETE), fip.state)
3080
+ fip_id = fip.FnGetRefId()
3081
+ self.assertEqual('fc68ea2c-b60b-4b4f-bd82-94ec81110766', fip_id)
3083
+ self.assertEqual(None, fip.FnGetAtt('status'))
3084
+ self.assertEqual('ACTIVE', fip.FnGetAtt('status'))
3086
+ fip.FnGetAtt('Foo')
3087
+ raise Exception('Expected InvalidTemplateAttribute')
3088
+ except exception.InvalidTemplateAttribute:
3091
+ self.assertEqual('fc68ea2c-b60b-4b4f-bd82-94ec81110766',
3092
+ fip.FnGetAtt('id'))
3093
+ self.assertRaises(resource.UpdateReplace,
3094
+ fip.handle_update, {}, {}, {})
3095
+ self.assertEqual(fip.delete(), None)
3096
+ fip.state_set(fip.CREATE, fip.COMPLETE, 'to delete again')
3097
+ self.assertEqual(fip.delete(), None)
3099
+ self.m.VerifyAll()
3101
+ def test_port(self):
3103
+ clients.OpenStackClients.keystone().AndReturn(
3104
+ fakes.FakeKeystoneClient())
3105
+ neutronclient.Client.create_port({'port': {
3106
+ 'network_id': u'xyz1234',
3108
+ {'subnet_id': u'12.12.12.0', 'ip_address': u'10.0.0.10'}
3110
+ 'name': utils.PhysName('test_stack', 'port_floating'),
3111
+ 'admin_state_up': True}}
3112
+ ).AndReturn({'port': {
3113
+ "status": "BUILD",
3114
+ "id": "fc68ea2c-b60b-4b4f-bd82-94ec81110766"
3116
+ neutronclient.Client.show_port(
3117
+ 'fc68ea2c-b60b-4b4f-bd82-94ec81110766'
3118
+ ).AndReturn({'port': {
3119
+ "status": "BUILD",
3120
+ "id": "fc68ea2c-b60b-4b4f-bd82-94ec81110766"
3122
+ neutronclient.Client.show_port(
3123
+ 'fc68ea2c-b60b-4b4f-bd82-94ec81110766'
3124
+ ).AndReturn({'port': {
3125
+ "status": "ACTIVE",
3126
+ "id": "fc68ea2c-b60b-4b4f-bd82-94ec81110766"
3128
+ neutronclient.Client.show_port(
3129
+ 'fc68ea2c-b60b-4b4f-bd82-94ec81110766'
3130
+ ).AndRaise(qe.NeutronClientException(status_code=404))
3131
+ neutronclient.Client.show_port(
3132
+ 'fc68ea2c-b60b-4b4f-bd82-94ec81110766'
3133
+ ).MultipleTimes().AndReturn({'port': {
3134
+ "status": "ACTIVE",
3135
+ "id": "fc68ea2c-b60b-4b4f-bd82-94ec81110766"
3138
+ self.m.ReplayAll()
3140
+ t = template_format.parse(neutron_floating_template)
3141
+ stack = parse_stack(t)
3143
+ p = stack['port_floating']
3144
+ scheduler.TaskRunner(p.create)()
3145
+ self.assertEqual((p.CREATE, p.COMPLETE), p.state)
3148
+ port_id = p.FnGetRefId()
3149
+ self.assertEqual('fc68ea2c-b60b-4b4f-bd82-94ec81110766', port_id)
3151
+ self.assertEqual(None, p.FnGetAtt('status'))
3152
+ self.assertEqual('ACTIVE', p.FnGetAtt('status'))
3155
+ raise Exception('Expected InvalidTemplateAttribute')
3156
+ except exception.InvalidTemplateAttribute:
3159
+ self.assertEqual('fc68ea2c-b60b-4b4f-bd82-94ec81110766',
3162
+ self.assertRaises(resource.UpdateReplace,
3163
+ p.handle_update, {}, {}, {})
3165
+ self.m.VerifyAll()
3167
+ def test_floatip_port(self):
3169
+ clients.OpenStackClients.keystone().AndReturn(
3170
+ fakes.FakeKeystoneClient())
3171
+ neutronclient.Client.create_floatingip({
3172
+ 'floatingip': {'floating_network_id': u'abcd1234'}
3173
+ }).AndReturn({'floatingip': {
3174
+ "status": "ACTIVE",
3175
+ "id": "fc68ea2c-b60b-4b4f-bd82-94ec81110766"
3178
+ neutronclient.Client.create_port({'port': {
3179
+ 'network_id': u'xyz1234',
3181
+ {'subnet_id': u'12.12.12.0', 'ip_address': u'10.0.0.10'}
3183
+ 'name': utils.PhysName('test_stack', 'port_floating'),
3184
+ 'admin_state_up': True}}
3185
+ ).AndReturn({'port': {
3186
+ "status": "BUILD",
3187
+ "id": "fc68ea2c-b60b-4b4f-bd82-94ec81110766"
3189
+ neutronclient.Client.show_port(
3190
+ 'fc68ea2c-b60b-4b4f-bd82-94ec81110766'
3191
+ ).AndReturn({'port': {
3192
+ "status": "ACTIVE",
3193
+ "id": "fc68ea2c-b60b-4b4f-bd82-94ec81110766"
3195
+ neutronclient.Client.update_floatingip(
3196
+ 'fc68ea2c-b60b-4b4f-bd82-94ec81110766',
3199
+ 'port_id': u'fc68ea2c-b60b-4b4f-bd82-94ec81110766'}}
3200
+ ).AndReturn({'floatingip': {
3201
+ "status": "ACTIVE",
3202
+ "id": "fc68ea2c-b60b-4b4f-bd82-94ec81110766"
3205
+ neutronclient.Client.update_floatingip(
3206
+ 'fc68ea2c-b60b-4b4f-bd82-94ec81110766',
3209
+ }}).AndReturn(None)
3211
+ neutronclient.Client.delete_port(
3212
+ 'fc68ea2c-b60b-4b4f-bd82-94ec81110766'
3215
+ neutronclient.Client.show_port(
3216
+ 'fc68ea2c-b60b-4b4f-bd82-94ec81110766'
3217
+ ).AndRaise(qe.NeutronClientException(status_code=404))
3219
+ neutronclient.Client.delete_floatingip(
3220
+ 'fc68ea2c-b60b-4b4f-bd82-94ec81110766'
3223
+ neutronclient.Client.update_floatingip(
3224
+ 'fc68ea2c-b60b-4b4f-bd82-94ec81110766',
3227
+ }}).AndRaise(qe.NeutronClientException(status_code=404))
3229
+ neutronclient.Client.delete_port(
3230
+ 'fc68ea2c-b60b-4b4f-bd82-94ec81110766'
3231
+ ).AndRaise(qe.NeutronClientException(status_code=404))
3233
+ neutronclient.Client.delete_floatingip(
3234
+ 'fc68ea2c-b60b-4b4f-bd82-94ec81110766'
3235
+ ).AndRaise(qe.NeutronClientException(status_code=404))
3237
+ self.m.ReplayAll()
3239
+ t = template_format.parse(neutron_floating_template)
3240
+ stack = parse_stack(t)
3242
+ fip = stack['floating_ip']
3243
+ scheduler.TaskRunner(fip.create)()
3244
+ self.assertEqual((fip.CREATE, fip.COMPLETE), fip.state)
3246
+ p = stack['port_floating']
3247
+ scheduler.TaskRunner(p.create)()
3248
+ self.assertEqual((p.CREATE, p.COMPLETE), p.state)
3250
+ fipa = stack['floating_ip_assoc']
3251
+ scheduler.TaskRunner(fipa.create)()
3252
+ self.assertEqual((fipa.CREATE, fipa.COMPLETE), fipa.state)
3256
+ fipa_id = fipa.FnGetRefId()
3257
+ fip_id = fip.FnGetRefId()
3258
+ port_id = p.FnGetRefId()
3259
+ self.assertEqual('%s:%s' % (fip_id, port_id), fipa_id)
3260
+ self.assertRaises(resource.UpdateReplace,
3261
+ fipa.handle_update, {}, {}, {})
3263
+ self.assertEqual(fipa.delete(), None)
3264
+ self.assertEqual(scheduler.TaskRunner(p.delete)(), None)
3265
+ self.assertEqual(fip.delete(), None)
3267
+ fipa.state_set(fipa.CREATE, fipa.COMPLETE, 'to delete again')
3268
+ fip.state_set(fip.CREATE, fip.COMPLETE, 'to delete again')
3269
+ p.state_set(p.CREATE, p.COMPLETE, 'to delete again')
3271
+ self.assertEqual(fipa.delete(), None)
3272
+ self.assertEqual(scheduler.TaskRunner(p.delete)(), None)
3273
+ self.assertEqual(fip.delete(), None)
3275
+ self.m.VerifyAll()
3276
diff -Naurp heat-2013.2.b2.orig/heat/tests/test_quantum.py heat-2013.2.b2/heat/tests/test_quantum.py
3277
--- heat-2013.2.b2.orig/heat/tests/test_quantum.py 2013-08-07 22:22:07.383156844 +0000
3278
+++ heat-2013.2.b2/heat/tests/test_quantum.py 1970-01-01 00:00:00.000000000 +0000
3280
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
3282
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
3283
-# not use this file except in compliance with the License. You may obtain
3284
-# a copy of the License at
3286
-# http://www.apache.org/licenses/LICENSE-2.0
3288
-# Unless required by applicable law or agreed to in writing, software
3289
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
3290
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
3291
-# License for the specific language governing permissions and limitations
3292
-# under the License.
3295
-from testtools import skipIf
3297
-from heat.common import exception
3298
-from heat.common import template_format
3299
-from heat.engine import properties
3300
-from heat.engine import resource
3301
-from heat.engine import scheduler
3302
-from heat.engine.resources.quantum import net
3303
-from heat.engine.resources.quantum import subnet
3304
-from heat.engine.resources.quantum import router
3305
-from heat.engine.resources.quantum.quantum import QuantumResource as qr
3306
-from heat.openstack.common.importutils import try_import
3307
-from heat.tests.common import HeatTestCase
3308
-from heat.tests import utils
3309
-from heat.tests.utils import setup_dummy_db
3310
-from heat.tests.utils import parse_stack
3312
-quantumclient = try_import('quantumclient.v2_0.client')
3313
-qe = try_import('quantumclient.common.exceptions')
3315
-quantum_template = '''
3317
- "AWSTemplateFormatVersion" : "2010-09-09",
3318
- "Description" : "Template to test Quantum resources",
3319
- "Parameters" : {},
3322
- "Type": "OS::Quantum::Net",
3324
- "name": "the_network"
3327
- "unnamed_network": {
3328
- "Type": "OS::Quantum::Net"
3330
- "admin_down_network": {
3331
- "Type": "OS::Quantum::Net",
3333
- "admin_state_up": false
3337
- "Type": "OS::Quantum::Subnet",
3339
- "network_id": { "Ref" : "network" },
3341
- "cidr": "10.0.3.0/24",
3342
- "allocation_pools": [{"start": "10.0.3.20", "end": "10.0.3.150"}],
3343
- "dns_nameservers": ["8.8.8.8"]
3347
- "Type": "OS::Quantum::Port",
3349
- "device_id": "d6b4d3a5-c700-476f-b609-1493dd9dadc0",
3351
- "network_id": { "Ref" : "network" },
3353
- "subnet_id": { "Ref" : "subnet" },
3354
- "ip_address": "10.0.3.21"
3359
- "Type": "OS::Quantum::Port",
3362
- "network_id": { "Ref" : "network" }
3366
- "Type": "OS::Quantum::Router"
3368
- "router_interface": {
3369
- "Type": "OS::Quantum::RouterInterface",
3371
- "router_id": { "Ref" : "router" },
3372
- "subnet_id": { "Ref" : "subnet" }
3376
- "Type": "OS::Quantum::RouterGateway",
3378
- "router_id": { "Ref" : "router" },
3379
- "network_id": { "Ref" : "network" }
3386
-quantum_floating_template = '''
3388
- "AWSTemplateFormatVersion" : "2010-09-09",
3389
- "Description" : "Template to test Quantum resources",
3390
- "Parameters" : {},
3392
- "port_floating": {
3393
- "Type": "OS::Quantum::Port",
3395
- "network_id": "xyz1234",
3397
- "subnet_id": "12.12.12.0",
3398
- "ip_address": "10.0.0.10"
3403
- "Type": "OS::Quantum::FloatingIP",
3405
- "floating_network_id": "abcd1234",
3408
- "floating_ip_assoc": {
3409
- "Type": "OS::Quantum::FloatingIPAssociation",
3411
- "floatingip_id": { "Ref" : "floating_ip" },
3412
- "port_id": { "Ref" : "port_floating" }
3416
- "Type": "OS::Quantum::Router"
3419
- "Type": "OS::Quantum::RouterGateway",
3421
- "router_id": { "Ref" : "router" },
3422
- "network_id": "abcd1234"
3430
-class QuantumTest(HeatTestCase):
3432
- def test_validate_properties(self):
3433
- vs = {'router:external': True}
3434
- data = {'admin_state_up': False,
3435
- 'value_specs': vs}
3436
- p = properties.Properties(net.Net.properties_schema, data)
3437
- self.assertEqual(None, qr.validate_properties(p))
3439
- vs['shared'] = True
3440
- self.assertEqual('shared not allowed in value_specs',
3441
- qr.validate_properties(p))
3444
- vs['name'] = 'foo'
3445
- self.assertEqual('name not allowed in value_specs',
3446
- qr.validate_properties(p))
3449
- vs['tenant_id'] = '1234'
3450
- self.assertEqual('tenant_id not allowed in value_specs',
3451
- qr.validate_properties(p))
3452
- vs.pop('tenant_id')
3454
- vs['foo'] = '1234'
3455
- self.assertEqual(None, qr.validate_properties(p))
3457
- def test_prepare_properties(self):
3458
- data = {'admin_state_up': False,
3459
- 'value_specs': {'router:external': True}}
3460
- p = properties.Properties(net.Net.properties_schema, data)
3461
- props = qr.prepare_properties(p, 'resource_name')
3462
- self.assertEqual({'name': 'resource_name',
3463
- 'router:external': True,
3464
- 'admin_state_up': False}, props)
3466
- def test_is_built(self):
3467
- self.assertTrue(qr.is_built({
3468
- 'name': 'the_net',
3469
- 'status': 'ACTIVE'
3471
- self.assertTrue(qr.is_built({
3472
- 'name': 'the_net',
3475
- self.assertFalse(qr.is_built({
3476
- 'name': 'the_net',
3479
- self.assertRaises(exception.Error, qr.is_built, {
3480
- 'name': 'the_net',
3481
- 'status': 'FROBULATING'
3485
-@skipIf(quantumclient is None, 'quantumclient unavailable')
3486
-class QuantumNetTest(HeatTestCase):
3489
- super(QuantumNetTest, self).setUp()
3490
- self.m.StubOutWithMock(quantumclient.Client, 'create_network')
3491
- self.m.StubOutWithMock(quantumclient.Client, 'delete_network')
3492
- self.m.StubOutWithMock(quantumclient.Client, 'show_network')
3495
- def create_net(self, t, stack, resource_name):
3496
- rsrc = net.Net('test_net', t['Resources'][resource_name], stack)
3497
- scheduler.TaskRunner(rsrc.create)()
3498
- self.assertEqual((rsrc.CREATE, rsrc.COMPLETE), rsrc.state)
3501
- def test_net(self):
3502
- quantumclient.Client.create_network({
3503
- 'network': {'name': u'the_network', 'admin_state_up': True}
3504
- }).AndReturn({"network": {
3505
- "status": "BUILD",
3508
- "admin_state_up": False,
3510
- "tenant_id": "c1210485b2424d48804aad5d39c61b8f",
3511
- "id": "fc68ea2c-b60b-4b4f-bd82-94ec81110766"
3514
- quantumclient.Client.show_network(
3515
- 'fc68ea2c-b60b-4b4f-bd82-94ec81110766'
3516
- ).AndReturn({"network": {
3517
- "status": "BUILD",
3520
- "admin_state_up": False,
3522
- "tenant_id": "c1210485b2424d48804aad5d39c61b8f",
3523
- "id": "fc68ea2c-b60b-4b4f-bd82-94ec81110766"
3526
- quantumclient.Client.show_network(
3527
- 'fc68ea2c-b60b-4b4f-bd82-94ec81110766'
3528
- ).AndReturn({"network": {
3529
- "status": "ACTIVE",
3532
- "admin_state_up": False,
3534
- "tenant_id": "c1210485b2424d48804aad5d39c61b8f",
3535
- "id": "fc68ea2c-b60b-4b4f-bd82-94ec81110766"
3538
- quantumclient.Client.show_network(
3539
- 'fc68ea2c-b60b-4b4f-bd82-94ec81110766'
3540
- ).AndRaise(qe.QuantumClientException(status_code=404))
3542
- quantumclient.Client.show_network(
3543
- 'fc68ea2c-b60b-4b4f-bd82-94ec81110766'
3544
- ).AndReturn({"network": {
3545
- "status": "ACTIVE",
3548
- "admin_state_up": False,
3550
- "tenant_id": "c1210485b2424d48804aad5d39c61b8f",
3551
- "id": "fc68ea2c-b60b-4b4f-bd82-94ec81110766"
3554
- quantumclient.Client.show_network(
3555
- 'fc68ea2c-b60b-4b4f-bd82-94ec81110766'
3556
- ).AndReturn({"network": {
3557
- "status": "ACTIVE",
3560
- "admin_state_up": False,
3562
- "tenant_id": "c1210485b2424d48804aad5d39c61b8f",
3563
- "id": "fc68ea2c-b60b-4b4f-bd82-94ec81110766"
3566
- quantumclient.Client.delete_network(
3567
- 'fc68ea2c-b60b-4b4f-bd82-94ec81110766'
3570
- quantumclient.Client.show_network(
3571
- 'fc68ea2c-b60b-4b4f-bd82-94ec81110766'
3572
- ).AndRaise(qe.QuantumClientException(status_code=404))
3574
- quantumclient.Client.delete_network(
3575
- 'fc68ea2c-b60b-4b4f-bd82-94ec81110766'
3576
- ).AndRaise(qe.QuantumClientException(status_code=404))
3578
- self.m.ReplayAll()
3579
- t = template_format.parse(quantum_template)
3580
- stack = parse_stack(t)
3581
- rsrc = self.create_net(t, stack, 'network')
3583
- # assert the implicit dependency between the gateway and the interface
3584
- deps = stack.dependencies[stack['router_interface']]
3585
- self.assertIn(stack['gateway'], deps)
3587
- # assert the implicit dependency between the gateway and the subnet
3588
- deps = stack.dependencies[stack['subnet']]
3589
- self.assertIn(stack['gateway'], deps)
3593
- ref_id = rsrc.FnGetRefId()
3594
- self.assertEqual('fc68ea2c-b60b-4b4f-bd82-94ec81110766', ref_id)
3596
- self.assertEqual(None, rsrc.FnGetAtt('status'))
3597
- self.assertEqual('ACTIVE', rsrc.FnGetAtt('status'))
3599
- rsrc.FnGetAtt('Foo')
3600
- raise Exception('Expected InvalidTemplateAttribute')
3601
- except exception.InvalidTemplateAttribute:
3604
- self.assertEqual('fc68ea2c-b60b-4b4f-bd82-94ec81110766',
3605
- rsrc.FnGetAtt('id'))
3607
- self.assertRaises(resource.UpdateReplace,
3608
- rsrc.handle_update, {}, {}, {})
3610
- scheduler.TaskRunner(rsrc.delete)()
3611
- rsrc.state_set(rsrc.CREATE, rsrc.COMPLETE, 'to delete again')
3612
- scheduler.TaskRunner(rsrc.delete)()
3613
- self.m.VerifyAll()
3616
-@skipIf(quantumclient is None, 'quantumclient unavailable')
3617
-class QuantumSubnetTest(HeatTestCase):
3620
- super(QuantumSubnetTest, self).setUp()
3621
- self.m.StubOutWithMock(quantumclient.Client, 'create_subnet')
3622
- self.m.StubOutWithMock(quantumclient.Client, 'delete_subnet')
3623
- self.m.StubOutWithMock(quantumclient.Client, 'show_subnet')
3626
- def create_subnet(self, t, stack, resource_name):
3627
- rsrc = subnet.Subnet('test_subnet', t['Resources'][resource_name],
3629
- scheduler.TaskRunner(rsrc.create)()
3630
- self.assertEqual((rsrc.CREATE, rsrc.COMPLETE), rsrc.state)
3633
- def test_subnet(self):
3635
- quantumclient.Client.create_subnet({
3637
- 'name': utils.PhysName('test_stack', 'test_subnet'),
3638
- 'network_id': u'None',
3639
- 'dns_nameservers': [u'8.8.8.8'],
3640
- 'allocation_pools': [
3641
- {'start': u'10.0.3.20', 'end': u'10.0.3.150'}],
3643
- 'cidr': u'10.0.3.0/24'
3647
- "allocation_pools": [
3648
- {"start": "10.0.3.20", "end": "10.0.3.150"}],
3649
- "cidr": "10.0.3.0/24",
3650
- "dns_nameservers": ["8.8.8.8"],
3651
- "enable_dhcp": True,
3652
- "gateway_ip": "10.0.3.1",
3653
- "id": "91e47a57-7508-46fe-afc9-fc454e8580e1",
3656
- "network_id": "fc68ea2c-b60b-4b4f-bd82-94ec81110766",
3657
- "tenant_id": "c1210485b2424d48804aad5d39c61b8f"
3660
- quantumclient.Client.show_subnet(
3661
- '91e47a57-7508-46fe-afc9-fc454e8580e1').AndRaise(
3662
- qe.QuantumClientException(status_code=404))
3666
- "network_id": "fc68ea2c-b60b-4b4f-bd82-94ec81110766",
3667
- "tenant_id": "c1210485b2424d48804aad5d39c61b8f",
3668
- "allocation_pools": [
3669
- {"start": "10.0.3.20", "end": "10.0.3.150"}],
3670
- "gateway_ip": "10.0.3.1",
3672
- "cidr": "10.0.3.0/24",
3673
- "dns_nameservers": ["8.8.8.8"],
3674
- "id": "91e47a57-7508-46fe-afc9-fc454e8580e1",
3675
- "enable_dhcp": True,
3678
- quantumclient.Client.show_subnet(
3679
- '91e47a57-7508-46fe-afc9-fc454e8580e1').AndReturn(sn)
3680
- quantumclient.Client.show_subnet(
3681
- '91e47a57-7508-46fe-afc9-fc454e8580e1').AndReturn(sn)
3682
- quantumclient.Client.show_subnet(
3683
- '91e47a57-7508-46fe-afc9-fc454e8580e1').AndReturn(sn)
3685
- quantumclient.Client.delete_subnet(
3686
- '91e47a57-7508-46fe-afc9-fc454e8580e1'
3689
- quantumclient.Client.show_subnet(
3690
- '91e47a57-7508-46fe-afc9-fc454e8580e1'
3691
- ).AndRaise(qe.QuantumClientException(status_code=404))
3693
- quantumclient.Client.delete_subnet(
3694
- '91e47a57-7508-46fe-afc9-fc454e8580e1'
3695
- ).AndRaise(qe.QuantumClientException(status_code=404))
3697
- self.m.ReplayAll()
3698
- t = template_format.parse(quantum_template)
3699
- stack = parse_stack(t)
3700
- rsrc = self.create_subnet(t, stack, 'subnet')
3704
- ref_id = rsrc.FnGetRefId()
3705
- self.assertEqual('91e47a57-7508-46fe-afc9-fc454e8580e1', ref_id)
3706
- self.assertEqual(None,
3707
- rsrc.FnGetAtt('network_id'))
3708
- self.assertEqual('fc68ea2c-b60b-4b4f-bd82-94ec81110766',
3709
- rsrc.FnGetAtt('network_id'))
3710
- self.assertEqual('8.8.8.8', rsrc.FnGetAtt('dns_nameservers')[0])
3711
- self.assertEqual('91e47a57-7508-46fe-afc9-fc454e8580e1',
3712
- rsrc.FnGetAtt('id'))
3714
- # assert the dependency (implicit or explicit) between the ports
3716
- self.assertIn(stack['port'], stack.dependencies[stack['subnet']])
3717
- self.assertIn(stack['port2'], stack.dependencies[stack['subnet']])
3719
- self.assertRaises(resource.UpdateReplace,
3720
- rsrc.handle_update, {}, {}, {})
3722
- self.assertEqual(scheduler.TaskRunner(rsrc.delete)(), None)
3723
- rsrc.state_set(rsrc.CREATE, rsrc.COMPLETE, 'to delete again')
3724
- self.assertEqual(scheduler.TaskRunner(rsrc.delete)(), None)
3725
- self.m.VerifyAll()
3727
- def test_subnet_disable_dhcp(self):
3729
- quantumclient.Client.create_subnet({
3731
- 'name': utils.PhysName('test_stack', 'test_subnet'),
3732
- 'network_id': u'None',
3733
- 'dns_nameservers': [u'8.8.8.8'],
3734
- 'allocation_pools': [
3735
- {'start': u'10.0.3.20', 'end': u'10.0.3.150'}],
3737
- 'enable_dhcp': False,
3738
- 'cidr': u'10.0.3.0/24'
3742
- "allocation_pools": [
3743
- {"start": "10.0.3.20", "end": "10.0.3.150"}],
3744
- "cidr": "10.0.3.0/24",
3745
- "dns_nameservers": ["8.8.8.8"],
3746
- "enable_dhcp": False,
3747
- "gateway_ip": "10.0.3.1",
3748
- "id": "91e47a57-7508-46fe-afc9-fc454e8580e1",
3751
- "network_id": "fc68ea2c-b60b-4b4f-bd82-94ec81110766",
3752
- "tenant_id": "c1210485b2424d48804aad5d39c61b8f"
3756
- quantumclient.Client.show_subnet(
3757
- '91e47a57-7508-46fe-afc9-fc454e8580e1').AndReturn({
3760
- "network_id": "fc68ea2c-b60b-4b4f-bd82-94ec81110766",
3761
- "tenant_id": "c1210485b2424d48804aad5d39c61b8f",
3762
- "allocation_pools": [
3763
- {"start": "10.0.3.20", "end": "10.0.3.150"}],
3764
- "gateway_ip": "10.0.3.1",
3766
- "cidr": "10.0.3.0/24",
3767
- "dns_nameservers": ["8.8.8.8"],
3768
- "id": "91e47a57-7508-46fe-afc9-fc454e8580e1",
3769
- "enable_dhcp": False,
3773
- quantumclient.Client.delete_subnet(
3774
- '91e47a57-7508-46fe-afc9-fc454e8580e1'
3777
- quantumclient.Client.show_subnet(
3778
- '91e47a57-7508-46fe-afc9-fc454e8580e1'
3779
- ).AndRaise(qe.QuantumClientException(status_code=404))
3781
- self.m.ReplayAll()
3782
- t = template_format.parse(quantum_template)
3783
- t['Resources']['subnet']['Properties']['enable_dhcp'] = 'False'
3784
- stack = parse_stack(t)
3785
- rsrc = self.create_subnet(t, stack, 'subnet')
3789
- ref_id = rsrc.FnGetRefId()
3790
- self.assertEqual('91e47a57-7508-46fe-afc9-fc454e8580e1', ref_id)
3791
- self.assertEqual(False, rsrc.FnGetAtt('enable_dhcp'))
3792
- self.assertEqual(rsrc.delete(), None)
3793
- self.m.VerifyAll()
3796
-@skipIf(quantumclient is None, 'quantumclient unavailable')
3797
-class QuantumRouterTest(HeatTestCase):
3799
- super(QuantumRouterTest, self).setUp()
3800
- self.m.StubOutWithMock(quantumclient.Client, 'create_router')
3801
- self.m.StubOutWithMock(quantumclient.Client, 'delete_router')
3802
- self.m.StubOutWithMock(quantumclient.Client, 'show_router')
3803
- self.m.StubOutWithMock(quantumclient.Client, 'add_interface_router')
3804
- self.m.StubOutWithMock(quantumclient.Client, 'remove_interface_router')
3805
- self.m.StubOutWithMock(quantumclient.Client, 'add_gateway_router')
3806
- self.m.StubOutWithMock(quantumclient.Client, 'remove_gateway_router')
3809
- def create_router(self, t, stack, resource_name):
3810
- rsrc = router.Router('router', t['Resources'][resource_name], stack)
3811
- scheduler.TaskRunner(rsrc.create)()
3812
- self.assertEqual((rsrc.CREATE, rsrc.COMPLETE), rsrc.state)
3815
- def create_router_interface(self, t, stack, resource_name, properties={}):
3816
- t['Resources'][resource_name]['Properties'] = properties
3817
- rsrc = router.RouterInterface(
3818
- 'router_interface',
3819
- t['Resources'][resource_name],
3821
- scheduler.TaskRunner(rsrc.create)()
3822
- self.assertEqual((rsrc.CREATE, rsrc.COMPLETE), rsrc.state)
3825
- def create_gateway_router(self, t, stack, resource_name, properties={}):
3826
- t['Resources'][resource_name]['Properties'] = properties
3827
- rsrc = router.RouterGateway(
3829
- t['Resources'][resource_name],
3831
- scheduler.TaskRunner(rsrc.create)()
3832
- self.assertEqual((rsrc.CREATE, rsrc.COMPLETE), rsrc.state)
3835
- def test_router(self):
3836
- quantumclient.Client.create_router({
3838
- 'name': utils.PhysName('test_stack', 'router'),
3839
- 'admin_state_up': True,
3843
- "status": "BUILD",
3844
- "external_gateway_info": None,
3845
- "name": utils.PhysName('test_stack', 'router'),
3846
- "admin_state_up": True,
3847
- "tenant_id": "3e21026f2dc94372b105808c0e721661",
3848
- "id": "3e46229d-8fce-4733-819a-b5fe630550f8"
3851
- quantumclient.Client.show_router(
3852
- '3e46229d-8fce-4733-819a-b5fe630550f8').AndReturn({
3854
- "status": "BUILD",
3855
- "external_gateway_info": None,
3856
- "name": utils.PhysName('test_stack', 'router'),
3857
- "admin_state_up": True,
3858
- "tenant_id": "3e21026f2dc94372b105808c0e721661",
3860
- "id": "3e46229d-8fce-4733-819a-b5fe630550f8"
3863
- quantumclient.Client.show_router(
3864
- '3e46229d-8fce-4733-819a-b5fe630550f8').AndReturn({
3866
- "status": "ACTIVE",
3867
- "external_gateway_info": None,
3868
- "name": utils.PhysName('test_stack', 'router'),
3869
- "admin_state_up": True,
3870
- "tenant_id": "3e21026f2dc94372b105808c0e721661",
3872
- "id": "3e46229d-8fce-4733-819a-b5fe630550f8"
3876
- quantumclient.Client.show_router(
3877
- '3e46229d-8fce-4733-819a-b5fe630550f8').AndRaise(
3878
- qe.QuantumClientException(status_code=404))
3879
- quantumclient.Client.show_router(
3880
- '3e46229d-8fce-4733-819a-b5fe630550f8').AndReturn({
3882
- "status": "ACTIVE",
3883
- "external_gateway_info": None,
3884
- "name": utils.PhysName('test_stack', 'router'),
3885
- "admin_state_up": True,
3886
- "tenant_id": "3e21026f2dc94372b105808c0e721661",
3888
- "id": "3e46229d-8fce-4733-819a-b5fe630550f8"
3891
- quantumclient.Client.show_router(
3892
- '3e46229d-8fce-4733-819a-b5fe630550f8').AndReturn({
3894
- "status": "ACTIVE",
3895
- "external_gateway_info": None,
3896
- "name": utils.PhysName('test_stack', 'router'),
3897
- "admin_state_up": True,
3898
- "tenant_id": "3e21026f2dc94372b105808c0e721661",
3900
- "id": "3e46229d-8fce-4733-819a-b5fe630550f8"
3904
- quantumclient.Client.delete_router(
3905
- '3e46229d-8fce-4733-819a-b5fe630550f8'
3908
- quantumclient.Client.show_router(
3909
- '3e46229d-8fce-4733-819a-b5fe630550f8'
3910
- ).AndRaise(qe.QuantumClientException(status_code=404))
3912
- quantumclient.Client.delete_router(
3913
- '3e46229d-8fce-4733-819a-b5fe630550f8'
3914
- ).AndRaise(qe.QuantumClientException(status_code=404))
3916
- self.m.ReplayAll()
3917
- t = template_format.parse(quantum_template)
3918
- stack = parse_stack(t)
3919
- rsrc = self.create_router(t, stack, 'router')
3923
- ref_id = rsrc.FnGetRefId()
3924
- self.assertEqual('3e46229d-8fce-4733-819a-b5fe630550f8', ref_id)
3925
- self.assertEqual(None,
3926
- rsrc.FnGetAtt('tenant_id'))
3927
- self.assertEqual('3e21026f2dc94372b105808c0e721661',
3928
- rsrc.FnGetAtt('tenant_id'))
3929
- self.assertEqual('3e46229d-8fce-4733-819a-b5fe630550f8',
3930
- rsrc.FnGetAtt('id'))
3932
- self.assertRaises(resource.UpdateReplace,
3933
- rsrc.handle_update, {}, {}, {})
3935
- self.assertEqual(scheduler.TaskRunner(rsrc.delete)(), None)
3936
- rsrc.state_set(rsrc.CREATE, rsrc.COMPLETE, 'to delete again')
3937
- self.assertEqual(scheduler.TaskRunner(rsrc.delete)(), None)
3938
- self.m.VerifyAll()
3940
- def test_router_interface(self):
3941
- quantumclient.Client.add_interface_router(
3942
- '3e46229d-8fce-4733-819a-b5fe630550f8',
3943
- {'subnet_id': '91e47a57-7508-46fe-afc9-fc454e8580e1'}
3945
- quantumclient.Client.remove_interface_router(
3946
- '3e46229d-8fce-4733-819a-b5fe630550f8',
3947
- {'subnet_id': '91e47a57-7508-46fe-afc9-fc454e8580e1'}
3949
- quantumclient.Client.remove_interface_router(
3950
- '3e46229d-8fce-4733-819a-b5fe630550f8',
3951
- {'subnet_id': '91e47a57-7508-46fe-afc9-fc454e8580e1'}
3952
- ).AndRaise(qe.QuantumClientException(status_code=404))
3953
- self.m.ReplayAll()
3954
- t = template_format.parse(quantum_template)
3955
- stack = parse_stack(t)
3957
- rsrc = self.create_router_interface(
3958
- t, stack, 'router_interface', properties={
3959
- 'router_id': '3e46229d-8fce-4733-819a-b5fe630550f8',
3960
- 'subnet_id': '91e47a57-7508-46fe-afc9-fc454e8580e1'
3963
- self.assertEqual(rsrc.delete(), None)
3964
- rsrc.state_set(rsrc.CREATE, rsrc.COMPLETE, 'to delete again')
3965
- self.assertEqual(rsrc.delete(), None)
3966
- self.m.VerifyAll()
3968
- def test_gateway_router(self):
3969
- quantumclient.Client.add_gateway_router(
3970
- '3e46229d-8fce-4733-819a-b5fe630550f8',
3971
- {'network_id': 'fc68ea2c-b60b-4b4f-bd82-94ec81110766'}
3973
- quantumclient.Client.remove_gateway_router(
3974
- '3e46229d-8fce-4733-819a-b5fe630550f8'
3976
- quantumclient.Client.remove_gateway_router(
3977
- '3e46229d-8fce-4733-819a-b5fe630550f8'
3978
- ).AndRaise(qe.QuantumClientException(status_code=404))
3979
- self.m.ReplayAll()
3980
- t = template_format.parse(quantum_template)
3981
- stack = parse_stack(t)
3983
- rsrc = self.create_gateway_router(
3984
- t, stack, 'gateway', properties={
3985
- 'router_id': '3e46229d-8fce-4733-819a-b5fe630550f8',
3986
- 'network_id': 'fc68ea2c-b60b-4b4f-bd82-94ec81110766'
3989
- self.assertEqual(rsrc.delete(), None)
3990
- rsrc.state_set(rsrc.CREATE, rsrc.COMPLETE, 'to delete again')
3991
- self.assertEqual(rsrc.delete(), None)
3992
- self.m.VerifyAll()
3995
-@skipIf(quantumclient is None, 'quantumclient unavailable')
3996
-class QuantumFloatingIPTest(HeatTestCase):
3997
- @skipIf(net.clients.quantumclient is None, "Missing Quantum Client")
3999
- super(QuantumFloatingIPTest, self).setUp()
4000
- self.m.StubOutWithMock(quantumclient.Client, 'create_floatingip')
4001
- self.m.StubOutWithMock(quantumclient.Client, 'delete_floatingip')
4002
- self.m.StubOutWithMock(quantumclient.Client, 'show_floatingip')
4003
- self.m.StubOutWithMock(quantumclient.Client, 'update_floatingip')
4004
- self.m.StubOutWithMock(quantumclient.Client, 'create_port')
4005
- self.m.StubOutWithMock(quantumclient.Client, 'delete_port')
4006
- self.m.StubOutWithMock(quantumclient.Client, 'show_port')
4009
- def test_floating_ip(self):
4011
- quantumclient.Client.create_floatingip({
4012
- 'floatingip': {'floating_network_id': u'abcd1234'}
4013
- }).AndReturn({'floatingip': {
4014
- "status": "ACTIVE",
4015
- "id": "fc68ea2c-b60b-4b4f-bd82-94ec81110766"
4018
- quantumclient.Client.show_floatingip(
4019
- 'fc68ea2c-b60b-4b4f-bd82-94ec81110766'
4020
- ).AndRaise(qe.QuantumClientException(status_code=404))
4021
- quantumclient.Client.show_floatingip(
4022
- 'fc68ea2c-b60b-4b4f-bd82-94ec81110766'
4023
- ).MultipleTimes().AndReturn({'floatingip': {
4024
- "status": "ACTIVE",
4025
- "id": "fc68ea2c-b60b-4b4f-bd82-94ec81110766"
4028
- quantumclient.Client.delete_floatingip(
4029
- 'fc68ea2c-b60b-4b4f-bd82-94ec81110766').AndReturn(None)
4030
- quantumclient.Client.delete_floatingip(
4031
- 'fc68ea2c-b60b-4b4f-bd82-94ec81110766').AndRaise(
4032
- qe.QuantumClientException(status_code=404))
4033
- self.m.ReplayAll()
4035
- t = template_format.parse(quantum_floating_template)
4036
- stack = parse_stack(t)
4038
- # assert the implicit dependency between the floating_ip
4040
- deps = stack.dependencies[stack['gateway']]
4041
- self.assertIn(stack['floating_ip'], deps)
4043
- fip = stack['floating_ip']
4044
- scheduler.TaskRunner(fip.create)()
4045
- self.assertEqual((fip.CREATE, fip.COMPLETE), fip.state)
4048
- fip_id = fip.FnGetRefId()
4049
- self.assertEqual('fc68ea2c-b60b-4b4f-bd82-94ec81110766', fip_id)
4051
- self.assertEqual(None, fip.FnGetAtt('status'))
4052
- self.assertEqual('ACTIVE', fip.FnGetAtt('status'))
4054
- fip.FnGetAtt('Foo')
4055
- raise Exception('Expected InvalidTemplateAttribute')
4056
- except exception.InvalidTemplateAttribute:
4059
- self.assertEqual('fc68ea2c-b60b-4b4f-bd82-94ec81110766',
4060
- fip.FnGetAtt('id'))
4061
- self.assertRaises(resource.UpdateReplace,
4062
- fip.handle_update, {}, {}, {})
4063
- self.assertEqual(fip.delete(), None)
4064
- fip.state_set(fip.CREATE, fip.COMPLETE, 'to delete again')
4065
- self.assertEqual(fip.delete(), None)
4067
- self.m.VerifyAll()
4069
- def test_port(self):
4071
- quantumclient.Client.create_port({'port': {
4072
- 'network_id': u'xyz1234',
4074
- {'subnet_id': u'12.12.12.0', 'ip_address': u'10.0.0.10'}
4076
- 'name': utils.PhysName('test_stack', 'port_floating'),
4077
- 'admin_state_up': True}}
4078
- ).AndReturn({'port': {
4079
- "status": "BUILD",
4080
- "id": "fc68ea2c-b60b-4b4f-bd82-94ec81110766"
4082
- quantumclient.Client.show_port(
4083
- 'fc68ea2c-b60b-4b4f-bd82-94ec81110766'
4084
- ).AndReturn({'port': {
4085
- "status": "BUILD",
4086
- "id": "fc68ea2c-b60b-4b4f-bd82-94ec81110766"
4088
- quantumclient.Client.show_port(
4089
- 'fc68ea2c-b60b-4b4f-bd82-94ec81110766'
4090
- ).AndReturn({'port': {
4091
- "status": "ACTIVE",
4092
- "id": "fc68ea2c-b60b-4b4f-bd82-94ec81110766"
4094
- quantumclient.Client.show_port(
4095
- 'fc68ea2c-b60b-4b4f-bd82-94ec81110766'
4096
- ).AndRaise(qe.QuantumClientException(status_code=404))
4097
- quantumclient.Client.show_port(
4098
- 'fc68ea2c-b60b-4b4f-bd82-94ec81110766'
4099
- ).MultipleTimes().AndReturn({'port': {
4100
- "status": "ACTIVE",
4101
- "id": "fc68ea2c-b60b-4b4f-bd82-94ec81110766"
4104
- self.m.ReplayAll()
4106
- t = template_format.parse(quantum_floating_template)
4107
- stack = parse_stack(t)
4109
- p = stack['port_floating']
4110
- scheduler.TaskRunner(p.create)()
4111
- self.assertEqual((p.CREATE, p.COMPLETE), p.state)
4114
- port_id = p.FnGetRefId()
4115
- self.assertEqual('fc68ea2c-b60b-4b4f-bd82-94ec81110766', port_id)
4117
- self.assertEqual(None, p.FnGetAtt('status'))
4118
- self.assertEqual('ACTIVE', p.FnGetAtt('status'))
4121
- raise Exception('Expected InvalidTemplateAttribute')
4122
- except exception.InvalidTemplateAttribute:
4125
- self.assertEqual('fc68ea2c-b60b-4b4f-bd82-94ec81110766',
4128
- self.assertRaises(resource.UpdateReplace,
4129
- p.handle_update, {}, {}, {})
4131
- self.m.VerifyAll()
4133
- def test_floatip_port(self):
4135
- quantumclient.Client.create_floatingip({
4136
- 'floatingip': {'floating_network_id': u'abcd1234'}
4137
- }).AndReturn({'floatingip': {
4138
- "status": "ACTIVE",
4139
- "id": "fc68ea2c-b60b-4b4f-bd82-94ec81110766"
4142
- quantumclient.Client.create_port({'port': {
4143
- 'network_id': u'xyz1234',
4145
- {'subnet_id': u'12.12.12.0', 'ip_address': u'10.0.0.10'}
4147
- 'name': utils.PhysName('test_stack', 'port_floating'),
4148
- 'admin_state_up': True}}
4149
- ).AndReturn({'port': {
4150
- "status": "BUILD",
4151
- "id": "fc68ea2c-b60b-4b4f-bd82-94ec81110766"
4153
- quantumclient.Client.show_port(
4154
- 'fc68ea2c-b60b-4b4f-bd82-94ec81110766'
4155
- ).AndReturn({'port': {
4156
- "status": "ACTIVE",
4157
- "id": "fc68ea2c-b60b-4b4f-bd82-94ec81110766"
4159
- quantumclient.Client.update_floatingip(
4160
- 'fc68ea2c-b60b-4b4f-bd82-94ec81110766',
4163
- 'port_id': u'fc68ea2c-b60b-4b4f-bd82-94ec81110766'}}
4164
- ).AndReturn({'floatingip': {
4165
- "status": "ACTIVE",
4166
- "id": "fc68ea2c-b60b-4b4f-bd82-94ec81110766"
4169
- quantumclient.Client.update_floatingip(
4170
- 'fc68ea2c-b60b-4b4f-bd82-94ec81110766',
4173
- }}).AndReturn(None)
4175
- quantumclient.Client.delete_port(
4176
- 'fc68ea2c-b60b-4b4f-bd82-94ec81110766'
4179
- quantumclient.Client.show_port(
4180
- 'fc68ea2c-b60b-4b4f-bd82-94ec81110766'
4181
- ).AndRaise(qe.QuantumClientException(status_code=404))
4183
- quantumclient.Client.delete_floatingip(
4184
- 'fc68ea2c-b60b-4b4f-bd82-94ec81110766'
4187
- quantumclient.Client.update_floatingip(
4188
- 'fc68ea2c-b60b-4b4f-bd82-94ec81110766',
4191
- }}).AndRaise(qe.QuantumClientException(status_code=404))
4193
- quantumclient.Client.delete_port(
4194
- 'fc68ea2c-b60b-4b4f-bd82-94ec81110766'
4195
- ).AndRaise(qe.QuantumClientException(status_code=404))
4197
- quantumclient.Client.delete_floatingip(
4198
- 'fc68ea2c-b60b-4b4f-bd82-94ec81110766'
4199
- ).AndRaise(qe.QuantumClientException(status_code=404))
4201
- self.m.ReplayAll()
4203
- t = template_format.parse(quantum_floating_template)
4204
- stack = parse_stack(t)
4206
- fip = stack['floating_ip']
4207
- scheduler.TaskRunner(fip.create)()
4208
- self.assertEqual((fip.CREATE, fip.COMPLETE), fip.state)
4210
- p = stack['port_floating']
4211
- scheduler.TaskRunner(p.create)()
4212
- self.assertEqual((p.CREATE, p.COMPLETE), p.state)
4214
- fipa = stack['floating_ip_assoc']
4215
- scheduler.TaskRunner(fipa.create)()
4216
- self.assertEqual((fipa.CREATE, fipa.COMPLETE), fipa.state)
4220
- fipa_id = fipa.FnGetRefId()
4221
- fip_id = fip.FnGetRefId()
4222
- port_id = p.FnGetRefId()
4223
- self.assertEqual('%s:%s' % (fip_id, port_id), fipa_id)
4224
- self.assertRaises(resource.UpdateReplace,
4225
- fipa.handle_update, {}, {}, {})
4227
- self.assertEqual(fipa.delete(), None)
4228
- self.assertEqual(scheduler.TaskRunner(p.delete)(), None)
4229
- self.assertEqual(fip.delete(), None)
4231
- fipa.state_set(fipa.CREATE, fipa.COMPLETE, 'to delete again')
4232
- fip.state_set(fip.CREATE, fip.COMPLETE, 'to delete again')
4233
- p.state_set(p.CREATE, p.COMPLETE, 'to delete again')
4235
- self.assertEqual(fipa.delete(), None)
4236
- self.assertEqual(scheduler.TaskRunner(p.delete)(), None)
4237
- self.assertEqual(fip.delete(), None)
4239
- self.m.VerifyAll()
4240
diff -Naurp heat-2013.2.b2.orig/heat/tests/test_security_group.py heat-2013.2.b2/heat/tests/test_security_group.py
4241
--- heat-2013.2.b2.orig/heat/tests/test_security_group.py 2013-08-07 22:22:07.383156844 +0000
4242
+++ heat-2013.2.b2/heat/tests/test_security_group.py 2013-08-07 22:31:33.999156844 +0000
4243
@@ -27,8 +27,8 @@ from heat.tests.utils import stack_delet
4245
from novaclient.v1_1 import security_groups as nova_sg
4246
from novaclient.v1_1 import security_group_rules as nova_sgr
4247
-from quantumclient.common.exceptions import QuantumClientException
4248
-from quantumclient.v2_0 import client as quantumclient
4249
+from neutronclient.common.exceptions import NeutronClientException
4250
+from neutronclient.v2_0 import client as neutronclient
4252
NovaSG = collections.namedtuple('NovaSG',
4254
@@ -59,7 +59,7 @@ Resources:
4258
- test_template_quantum = '''
4259
+ test_template_neutron = '''
4260
HeatTemplateFormatVersion: '2012-12-12'
4263
@@ -94,13 +94,13 @@ Resources:
4264
self.m.StubOutWithMock(nova_sg.SecurityGroupManager, 'get')
4265
self.m.StubOutWithMock(nova_sg.SecurityGroupManager, 'list')
4267
- self.m.StubOutWithMock(quantumclient.Client, 'create_security_group')
4268
+ self.m.StubOutWithMock(neutronclient.Client, 'create_security_group')
4269
self.m.StubOutWithMock(
4270
- quantumclient.Client, 'create_security_group_rule')
4271
- self.m.StubOutWithMock(quantumclient.Client, 'show_security_group')
4272
+ neutronclient.Client, 'create_security_group_rule')
4273
+ self.m.StubOutWithMock(neutronclient.Client, 'show_security_group')
4274
self.m.StubOutWithMock(
4275
- quantumclient.Client, 'delete_security_group_rule')
4276
- self.m.StubOutWithMock(quantumclient.Client, 'delete_security_group')
4277
+ neutronclient.Client, 'delete_security_group_rule')
4278
+ self.m.StubOutWithMock(neutronclient.Client, 'delete_security_group')
4280
def create_stack(self, template):
4281
t = template_format.parse(template)
4282
@@ -278,10 +278,10 @@ Resources:
4286
- def test_security_group_quantum(self):
4287
+ def test_security_group_neutron(self):
4289
sg_name = utils.PhysName('test_stack', 'the_sg')
4290
- quantumclient.Client.create_security_group({
4291
+ neutronclient.Client.create_security_group({
4294
'description': 'HTTP and SSH access'
4295
@@ -296,7 +296,7 @@ Resources:
4299
- quantumclient.Client.create_security_group_rule({
4300
+ neutronclient.Client.create_security_group_rule({
4301
'security_group_rule': {
4302
'direction': 'ingress',
4303
'remote_ip_prefix': '0.0.0.0/0',
4304
@@ -318,7 +318,7 @@ Resources:
4308
- quantumclient.Client.create_security_group_rule({
4309
+ neutronclient.Client.create_security_group_rule({
4310
'security_group_rule': {
4311
'direction': 'ingress',
4312
'remote_ip_prefix': '0.0.0.0/0',
4313
@@ -340,7 +340,7 @@ Resources:
4317
- quantumclient.Client.create_security_group_rule({
4318
+ neutronclient.Client.create_security_group_rule({
4319
'security_group_rule': {
4320
'direction': 'egress',
4321
'remote_ip_prefix': '10.0.1.0/24',
4322
@@ -364,7 +364,7 @@ Resources:
4326
- quantumclient.Client.show_security_group('aaaa').AndReturn({
4327
+ neutronclient.Client.show_security_group('aaaa').AndReturn({
4329
'tenant_id': 'f18ca530cc05425e8bac0a5ff92f7e88',
4331
@@ -401,13 +401,13 @@ Resources:
4332
'port_range_min': 22
4335
- quantumclient.Client.delete_security_group_rule('bbbb').AndReturn(None)
4336
- quantumclient.Client.delete_security_group_rule('cccc').AndReturn(None)
4337
- quantumclient.Client.delete_security_group_rule('dddd').AndReturn(None)
4338
- quantumclient.Client.delete_security_group('aaaa').AndReturn(None)
4339
+ neutronclient.Client.delete_security_group_rule('bbbb').AndReturn(None)
4340
+ neutronclient.Client.delete_security_group_rule('cccc').AndReturn(None)
4341
+ neutronclient.Client.delete_security_group_rule('dddd').AndReturn(None)
4342
+ neutronclient.Client.delete_security_group('aaaa').AndReturn(None)
4345
- stack = self.create_stack(self.test_template_quantum)
4346
+ stack = self.create_stack(self.test_template_neutron)
4348
sg = stack['the_sg']
4349
self.assertRaises(resource.UpdateReplace, sg.handle_update, {}, {}, {})
4350
@@ -418,10 +418,10 @@ Resources:
4354
- def test_security_group_quantum_exception(self):
4355
+ def test_security_group_neutron_exception(self):
4357
sg_name = utils.PhysName('test_stack', 'the_sg')
4358
- quantumclient.Client.create_security_group({
4359
+ neutronclient.Client.create_security_group({
4362
'description': 'HTTP and SSH access'
4363
@@ -436,7 +436,7 @@ Resources:
4367
- quantumclient.Client.create_security_group_rule({
4368
+ neutronclient.Client.create_security_group_rule({
4369
'security_group_rule': {
4370
'direction': 'ingress',
4371
'remote_ip_prefix': '0.0.0.0/0',
4372
@@ -447,8 +447,8 @@ Resources:
4373
'security_group_id': 'aaaa'
4376
- QuantumClientException(status_code=409))
4377
- quantumclient.Client.create_security_group_rule({
4378
+ NeutronClientException(status_code=409))
4379
+ neutronclient.Client.create_security_group_rule({
4380
'security_group_rule': {
4381
'direction': 'ingress',
4382
'remote_ip_prefix': '0.0.0.0/0',
4383
@@ -459,8 +459,8 @@ Resources:
4384
'security_group_id': 'aaaa'
4387
- QuantumClientException(status_code=409))
4388
- quantumclient.Client.create_security_group_rule({
4389
+ NeutronClientException(status_code=409))
4390
+ neutronclient.Client.create_security_group_rule({
4391
'security_group_rule': {
4392
'direction': 'egress',
4393
'remote_ip_prefix': '10.0.1.0/24',
4394
@@ -471,10 +471,10 @@ Resources:
4395
'security_group_id': 'aaaa'
4398
- QuantumClientException(status_code=409))
4399
+ NeutronClientException(status_code=409))
4402
- quantumclient.Client.show_security_group('aaaa').AndReturn({
4403
+ neutronclient.Client.show_security_group('aaaa').AndReturn({
4405
'tenant_id': 'f18ca530cc05425e8bac0a5ff92f7e88',
4407
@@ -511,20 +511,20 @@ Resources:
4408
'port_range_min': 22
4411
- quantumclient.Client.delete_security_group_rule('bbbb').AndRaise(
4412
- QuantumClientException(status_code=404))
4413
- quantumclient.Client.delete_security_group_rule('cccc').AndRaise(
4414
- QuantumClientException(status_code=404))
4415
- quantumclient.Client.delete_security_group_rule('dddd').AndRaise(
4416
- QuantumClientException(status_code=404))
4417
- quantumclient.Client.delete_security_group('aaaa').AndRaise(
4418
- QuantumClientException(status_code=404))
4419
+ neutronclient.Client.delete_security_group_rule('bbbb').AndRaise(
4420
+ NeutronClientException(status_code=404))
4421
+ neutronclient.Client.delete_security_group_rule('cccc').AndRaise(
4422
+ NeutronClientException(status_code=404))
4423
+ neutronclient.Client.delete_security_group_rule('dddd').AndRaise(
4424
+ NeutronClientException(status_code=404))
4425
+ neutronclient.Client.delete_security_group('aaaa').AndRaise(
4426
+ NeutronClientException(status_code=404))
4428
- quantumclient.Client.show_security_group('aaaa').AndRaise(
4429
- QuantumClientException(status_code=404))
4430
+ neutronclient.Client.show_security_group('aaaa').AndRaise(
4431
+ NeutronClientException(status_code=404))
4434
- stack = self.create_stack(self.test_template_quantum)
4435
+ stack = self.create_stack(self.test_template_neutron)
4437
sg = stack['the_sg']
4438
self.assertRaises(resource.UpdateReplace, sg.handle_update, {}, {}, {})
4439
diff -Naurp heat-2013.2.b2.orig/heat/tests/test_template_format.py heat-2013.2.b2/heat/tests/test_template_format.py
4440
--- heat-2013.2.b2.orig/heat/tests/test_template_format.py 2013-08-07 22:22:07.383156844 +0000
4441
+++ heat-2013.2.b2/heat/tests/test_template_format.py 2013-08-07 22:24:27.591156844 +0000
4442
@@ -151,9 +151,9 @@ class JsonYamlResolvedCompareTest(HeatTe
4443
for key in stack1.resources:
4444
self.assertEqual(stack1.resources[key].t, stack2.resources[key].t)
4446
- @skipIf(clients.quantumclient is None, 'quantumclient unavailable')
4447
- def test_quantum_resolved(self):
4448
- self.compare_stacks('Quantum.template', 'Quantum.yaml', {})
4449
+ @skipIf(clients.neutronclient is None, 'neutronclient unavailable')
4450
+ def test_neutron_resolved(self):
4451
+ self.compare_stacks('Neutron.template', 'Neutron.yaml', {})
4453
def test_wordpress_resolved(self):
4454
self.compare_stacks('WordPress_Single_Instance.template',
4455
diff -Naurp heat-2013.2.b2.orig/heat/tests/test_vpc.py heat-2013.2.b2/heat/tests/test_vpc.py
4456
--- heat-2013.2.b2.orig/heat/tests/test_vpc.py 2013-08-07 22:22:07.383156844 +0000
4457
+++ heat-2013.2.b2/heat/tests/test_vpc.py 2013-08-07 22:28:07.643156844 +0000
4458
@@ -24,42 +24,42 @@ from heat.tests import utils
4459
from heat.tests.utils import setup_dummy_db
4462
- from quantumclient.common.exceptions import QuantumClientException
4463
- from quantumclient.v2_0 import client as quantumclient
4464
+ from neutronclient.common.exceptions import NeutronClientException
4465
+ from neutronclient.v2_0 import client as neutronclient
4467
- quantumclient = None
4468
+ neutronclient = None
4471
class VPCTestBase(HeatTestCase):
4473
- @skipIf(quantumclient is None, 'quantumclient unavaialble')
4474
+ @skipIf(neutronclient is None, 'neutronclient unavaialble')
4476
super(VPCTestBase, self).setUp()
4478
- self.m.StubOutWithMock(quantumclient.Client, 'add_interface_router')
4479
- self.m.StubOutWithMock(quantumclient.Client, 'add_gateway_router')
4480
- self.m.StubOutWithMock(quantumclient.Client, 'create_network')
4481
- self.m.StubOutWithMock(quantumclient.Client, 'create_port')
4482
- self.m.StubOutWithMock(quantumclient.Client, 'create_router')
4483
- self.m.StubOutWithMock(quantumclient.Client, 'create_subnet')
4484
- self.m.StubOutWithMock(quantumclient.Client, 'delete_network')
4485
- self.m.StubOutWithMock(quantumclient.Client, 'delete_port')
4486
- self.m.StubOutWithMock(quantumclient.Client, 'delete_router')
4487
- self.m.StubOutWithMock(quantumclient.Client, 'delete_subnet')
4488
- self.m.StubOutWithMock(quantumclient.Client, 'list_networks')
4489
- self.m.StubOutWithMock(quantumclient.Client, 'list_routers')
4490
- self.m.StubOutWithMock(quantumclient.Client, 'remove_gateway_router')
4491
- self.m.StubOutWithMock(quantumclient.Client, 'remove_interface_router')
4492
- self.m.StubOutWithMock(quantumclient.Client, 'show_subnet')
4493
- self.m.StubOutWithMock(quantumclient.Client, 'show_network')
4494
- self.m.StubOutWithMock(quantumclient.Client, 'show_router')
4495
- self.m.StubOutWithMock(quantumclient.Client, 'create_security_group')
4496
- self.m.StubOutWithMock(quantumclient.Client, 'show_security_group')
4497
- self.m.StubOutWithMock(quantumclient.Client, 'delete_security_group')
4498
+ self.m.StubOutWithMock(neutronclient.Client, 'add_interface_router')
4499
+ self.m.StubOutWithMock(neutronclient.Client, 'add_gateway_router')
4500
+ self.m.StubOutWithMock(neutronclient.Client, 'create_network')
4501
+ self.m.StubOutWithMock(neutronclient.Client, 'create_port')
4502
+ self.m.StubOutWithMock(neutronclient.Client, 'create_router')
4503
+ self.m.StubOutWithMock(neutronclient.Client, 'create_subnet')
4504
+ self.m.StubOutWithMock(neutronclient.Client, 'delete_network')
4505
+ self.m.StubOutWithMock(neutronclient.Client, 'delete_port')
4506
+ self.m.StubOutWithMock(neutronclient.Client, 'delete_router')
4507
+ self.m.StubOutWithMock(neutronclient.Client, 'delete_subnet')
4508
+ self.m.StubOutWithMock(neutronclient.Client, 'list_networks')
4509
+ self.m.StubOutWithMock(neutronclient.Client, 'list_routers')
4510
+ self.m.StubOutWithMock(neutronclient.Client, 'remove_gateway_router')
4511
+ self.m.StubOutWithMock(neutronclient.Client, 'remove_interface_router')
4512
+ self.m.StubOutWithMock(neutronclient.Client, 'show_subnet')
4513
+ self.m.StubOutWithMock(neutronclient.Client, 'show_network')
4514
+ self.m.StubOutWithMock(neutronclient.Client, 'show_router')
4515
+ self.m.StubOutWithMock(neutronclient.Client, 'create_security_group')
4516
+ self.m.StubOutWithMock(neutronclient.Client, 'show_security_group')
4517
+ self.m.StubOutWithMock(neutronclient.Client, 'delete_security_group')
4518
self.m.StubOutWithMock(
4519
- quantumclient.Client, 'create_security_group_rule')
4520
+ neutronclient.Client, 'create_security_group_rule')
4521
self.m.StubOutWithMock(
4522
- quantumclient.Client, 'delete_security_group_rule')
4523
+ neutronclient.Client, 'delete_security_group_rule')
4525
def create_stack(self, template):
4526
t = template_format.parse(template)
4527
@@ -81,7 +81,7 @@ class VPCTestBase(HeatTestCase):
4529
def mock_create_network(self):
4530
self.vpc_name = utils.PhysName('test_stack', 'the_vpc')
4531
- quantumclient.Client.create_network(
4532
+ neutronclient.Client.create_network(
4534
'network': {'name': self.vpc_name}
4535
}).AndReturn({'network': {
4536
@@ -93,7 +93,7 @@ class VPCTestBase(HeatTestCase):
4537
'tenant_id': 'c1210485b2424d48804aad5d39c61b8f',
4540
- quantumclient.Client.show_network(
4541
+ neutronclient.Client.show_network(
4543
).AndReturn({"network": {
4545
@@ -105,7 +105,7 @@ class VPCTestBase(HeatTestCase):
4549
- quantumclient.Client.show_network(
4550
+ neutronclient.Client.show_network(
4552
).MultipleTimes().AndReturn({"network": {
4554
@@ -116,7 +116,7 @@ class VPCTestBase(HeatTestCase):
4555
"tenant_id": "c1210485b2424d48804aad5d39c61b8f",
4558
- quantumclient.Client.create_router(
4559
+ neutronclient.Client.create_router(
4560
{'router': {'name': self.vpc_name}}).AndReturn({
4563
@@ -125,7 +125,7 @@ class VPCTestBase(HeatTestCase):
4564
'tenant_id': 'c1210485b2424d48804aad5d39c61b8f',
4567
- quantumclient.Client.list_routers(name=self.vpc_name).AndReturn({
4568
+ neutronclient.Client.list_routers(name=self.vpc_name).AndReturn({
4571
"external_gateway_info": None,
4572
@@ -140,7 +140,7 @@ class VPCTestBase(HeatTestCase):
4574
def mock_create_subnet(self):
4575
self.subnet_name = utils.PhysName('test_stack', 'the_subnet')
4576
- quantumclient.Client.create_subnet(
4577
+ neutronclient.Client.create_subnet(
4579
'network_id': u'aaaa',
4580
'cidr': u'10.0.0.0/24',
4581
@@ -153,12 +153,12 @@ class VPCTestBase(HeatTestCase):
4582
'tenant_id': 'c1210485b2424d48804aad5d39c61b8f',
4584
self.mock_router_for_vpc()
4585
- quantumclient.Client.add_interface_router(
4586
+ neutronclient.Client.add_interface_router(
4588
{'subnet_id': 'cccc'}).AndReturn(None)
4590
def mock_show_subnet(self):
4591
- quantumclient.Client.show_subnet('cccc').AndReturn({
4592
+ neutronclient.Client.show_subnet('cccc').AndReturn({
4594
'name': self.subnet_name,
4595
'network_id': 'aaaa',
4596
@@ -174,7 +174,7 @@ class VPCTestBase(HeatTestCase):
4598
def mock_create_security_group(self):
4599
self.sg_name = utils.PhysName('test_stack', 'the_sg')
4600
- quantumclient.Client.create_security_group({
4601
+ neutronclient.Client.create_security_group({
4603
'name': self.sg_name,
4604
'description': 'SSH access'
4605
@@ -189,7 +189,7 @@ class VPCTestBase(HeatTestCase):
4609
- quantumclient.Client.create_security_group_rule({
4610
+ neutronclient.Client.create_security_group_rule({
4611
'security_group_rule': {
4612
'direction': 'ingress',
4613
'remote_ip_prefix': '0.0.0.0/0',
4614
@@ -214,7 +214,7 @@ class VPCTestBase(HeatTestCase):
4616
def mock_delete_security_group(self):
4617
sg_name = utils.PhysName('test_stack', 'the_sg')
4618
- quantumclient.Client.show_security_group('eeee').AndReturn({
4619
+ neutronclient.Client.show_security_group('eeee').AndReturn({
4621
'tenant_id': 'c1210485b2424d48804aad5d39c61b8f',
4623
@@ -231,11 +231,11 @@ class VPCTestBase(HeatTestCase):
4624
'port_range_min': 22
4627
- quantumclient.Client.delete_security_group_rule('bbbb').AndReturn(None)
4628
- quantumclient.Client.delete_security_group('eeee').AndReturn(None)
4629
+ neutronclient.Client.delete_security_group_rule('bbbb').AndReturn(None)
4630
+ neutronclient.Client.delete_security_group('eeee').AndReturn(None)
4632
def mock_router_for_vpc(self):
4633
- quantumclient.Client.list_routers(name=self.vpc_name).AndReturn({
4634
+ neutronclient.Client.list_routers(name=self.vpc_name).AndReturn({
4637
"external_gateway_info": {
4638
@@ -251,19 +251,19 @@ class VPCTestBase(HeatTestCase):
4640
def mock_delete_network(self):
4641
self.mock_router_for_vpc()
4642
- quantumclient.Client.delete_router('bbbb').AndReturn(None)
4643
- quantumclient.Client.delete_network('aaaa').AndReturn(None)
4644
+ neutronclient.Client.delete_router('bbbb').AndReturn(None)
4645
+ neutronclient.Client.delete_network('aaaa').AndReturn(None)
4647
def mock_delete_subnet(self):
4648
self.mock_router_for_vpc()
4649
- quantumclient.Client.remove_interface_router(
4650
+ neutronclient.Client.remove_interface_router(
4652
{'subnet_id': 'cccc'}).AndReturn(None)
4653
- quantumclient.Client.delete_subnet('cccc').AndReturn(None)
4654
+ neutronclient.Client.delete_subnet('cccc').AndReturn(None)
4656
def mock_create_route_table(self):
4657
self.rt_name = utils.PhysName('test_stack', 'the_route_table')
4658
- quantumclient.Client.create_router({
4659
+ neutronclient.Client.create_router({
4660
'router': {'name': self.rt_name}}).AndReturn({
4663
@@ -273,7 +273,7 @@ class VPCTestBase(HeatTestCase):
4667
- quantumclient.Client.show_router('ffff').AndReturn({
4668
+ neutronclient.Client.show_router('ffff').AndReturn({
4671
'name': self.rt_name,
4672
@@ -282,7 +282,7 @@ class VPCTestBase(HeatTestCase):
4676
- quantumclient.Client.show_router('ffff').AndReturn({
4677
+ neutronclient.Client.show_router('ffff').AndReturn({
4680
'name': self.rt_name,
4681
@@ -292,32 +292,32 @@ class VPCTestBase(HeatTestCase):
4684
self.mock_router_for_vpc()
4685
- quantumclient.Client.add_gateway_router(
4686
+ neutronclient.Client.add_gateway_router(
4687
'ffff', {'network_id': 'zzzz'}).AndReturn(None)
4689
def mock_create_association(self):
4690
self.mock_show_subnet()
4691
self.mock_router_for_vpc()
4692
- quantumclient.Client.remove_interface_router(
4693
+ neutronclient.Client.remove_interface_router(
4695
{'subnet_id': u'cccc'}).AndReturn(None)
4696
- quantumclient.Client.add_interface_router(
4697
+ neutronclient.Client.add_interface_router(
4699
{'subnet_id': 'cccc'}).AndReturn(None)
4701
def mock_delete_association(self):
4702
self.mock_show_subnet()
4703
self.mock_router_for_vpc()
4704
- quantumclient.Client.remove_interface_router(
4705
+ neutronclient.Client.remove_interface_router(
4707
{'subnet_id': u'cccc'}).AndReturn(None)
4708
- quantumclient.Client.add_interface_router(
4709
+ neutronclient.Client.add_interface_router(
4711
{'subnet_id': 'cccc'}).AndReturn(None)
4713
def mock_delete_route_table(self):
4714
- quantumclient.Client.delete_router('ffff').AndReturn(None)
4715
- quantumclient.Client.remove_gateway_router('ffff').AndReturn(None)
4716
+ neutronclient.Client.delete_router('ffff').AndReturn(None)
4717
+ neutronclient.Client.remove_gateway_router('ffff').AndReturn(None)
4719
def assertResourceState(self, resource, ref_id):
4720
self.assertEqual(None, resource.validate())
4721
@@ -374,12 +374,12 @@ Resources:
4723
# mock delete subnet which is already deleted
4724
self.mock_router_for_vpc()
4725
- quantumclient.Client.remove_interface_router(
4726
+ neutronclient.Client.remove_interface_router(
4728
{'subnet_id': 'cccc'}).AndRaise(
4729
- QuantumClientException(status_code=404))
4730
- quantumclient.Client.delete_subnet('cccc').AndRaise(
4731
- QuantumClientException(status_code=404))
4732
+ NeutronClientException(status_code=404))
4733
+ neutronclient.Client.delete_subnet('cccc').AndRaise(
4734
+ NeutronClientException(status_code=404))
4737
stack = self.create_stack(self.test_template)
4738
@@ -519,7 +519,7 @@ Resources:
4740
port['security_groups'] = security_groups
4742
- quantumclient.Client.create_port({'port': port}).AndReturn({
4743
+ neutronclient.Client.create_port({'port': port}).AndReturn({
4745
'admin_state_up': True,
4747
@@ -540,7 +540,7 @@ Resources:
4750
def mock_delete_network_interface(self):
4751
- quantumclient.Client.delete_port('dddd').AndReturn(None)
4752
+ neutronclient.Client.delete_port('dddd').AndReturn(None)
4754
def test_network_interface(self):
4755
self.mock_create_security_group()
4756
@@ -652,7 +652,7 @@ Resources:
4759
def mock_create_internet_gateway(self):
4760
- quantumclient.Client.list_networks(
4761
+ neutronclient.Client.list_networks(
4762
**{'router:external': True}).AndReturn({'networks': [{
4765
@@ -665,11 +665,11 @@ Resources:
4768
def mock_create_gateway_attachment(self):
4769
- quantumclient.Client.add_gateway_router(
4770
+ neutronclient.Client.add_gateway_router(
4771
'ffff', {'network_id': 'eeee'}).AndReturn(None)
4773
def mock_delete_gateway_attachment(self):
4774
- quantumclient.Client.remove_gateway_router('ffff').AndReturn(None)
4775
+ neutronclient.Client.remove_gateway_router('ffff').AndReturn(None)
4777
def test_internet_gateway(self):
4778
self.mock_create_internet_gateway()
4779
diff -Naurp heat-2013.2.b2.orig/README.rst heat-2013.2.b2/README.rst
4780
--- heat-2013.2.b2.orig/README.rst 2013-08-07 22:22:07.367156844 +0000
4781
+++ heat-2013.2.b2/README.rst 2013-08-07 22:24:21.095156844 +0000
4782
@@ -36,4 +36,4 @@ We have integration with
4783
* https://github.com/openstack/python-novaclient (instance)
4784
* https://github.com/openstack/python-keystoneclient (auth)
4785
* https://github.com/openstack/python-swiftclient (s3)
4786
-* https://github.com/openstack/python-quantumclient (networking)
4787
+* https://github.com/openstack/python-neutronclient (networking)
4788
diff -Naurp heat-2013.2.b2.orig/requirements.txt heat-2013.2.b2/requirements.txt
4789
--- heat-2013.2.b2.orig/requirements.txt 2013-08-07 22:22:07.367156844 +0000
4790
+++ heat-2013.2.b2/requirements.txt 2013-08-07 22:25:21.199156844 +0000
4791
@@ -18,7 +18,7 @@ SQLAlchemy>=0.7.8,<0.8.99
4793
python-keystoneclient>=0.2.1
4794
python-swiftclient>=1.2
4795
-python-quantumclient>=2.2.0
4796
+python-neutronclient>=2.2.0,<3
4797
python-cinderclient>=1.0.4