~ubuntu-branches/ubuntu/trusty/heat/trusty

« back to all changes in this revision

Viewing changes to debian/patches/rename-quantumclient.patch

  • Committer: Package Import Robot
  • Author(s): Chuck Short, Chuck Short
  • Date: 2013-08-08 01:08:42 UTC
  • Revision ID: package-import@ubuntu.com-20130808010842-77cni2v4vlib7rus
Tags: 2013.2~b2-0ubuntu4
[ Chuck Short ]
* debian/rules: Enable testsuite during builds.
* debian/patches/fix-sqlalchemy-0.8.patch: Build against sqlalchemy 0.8.
* debian/patches/rename-quantumclient.patch: quantumclient -> neutronclient.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
Description: Rename quantumclient to neutronclient
 
2
Author: Chuck Short <zulcss@ubuntu.com>
 
3
Forwarded: No
 
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
 
7
@@ -5,7 +5,7 @@
 
8
     xmlns:svg="http://www.w3.org/2000/svg"
 
9
     xmlns:html="http://www.w3.org/1999/xhtml"
 
10
     version="5.0"
 
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:
 
20
     swiftclient = None
 
21
     logger.info('swiftclient not available')
 
22
 try:
 
23
-    from quantumclient.v2_0 import client as quantumclient
 
24
+    from neutronclient.v2_0 import client as neutronclient
 
25
 except ImportError:
 
26
-    quantumclient = None
 
27
-    logger.info('quantumclient not available')
 
28
+    neutronclient = None
 
29
+    logger.info('neutronclient not available')
 
30
 try:
 
31
     from cinderclient import client as cinderclient
 
32
 except ImportError:
 
33
@@ -58,7 +58,7 @@ class OpenStackClients(object):
 
34
         self._nova = {}
 
35
         self._keystone = None
 
36
         self._swift = None
 
37
-        self._quantum = None
 
38
+        self._neutron = None
 
39
         self._cinder = None
 
40
 
 
41
     def keystone(self):
 
42
@@ -130,12 +130,12 @@ class OpenStackClients(object):
 
43
         self._swift = swiftclient.Connection(**args)
 
44
         return self._swift
 
45
 
 
46
-    def quantum(self):
 
47
-        if quantumclient is None:
 
48
+    def neutron(self):
 
49
+        if neutronclient is None:
 
50
             return None
 
51
-        if self._quantum:
 
52
-            logger.debug('using existing _quantum')
 
53
-            return self._quantum
 
54
+        if self._neutron:
 
55
+            logger.debug('using existing _neutron')
 
56
+            return self._neutron
 
57
 
 
58
         con = self.context
 
59
         args = {
 
60
@@ -154,11 +154,11 @@ class OpenStackClients(object):
 
61
             logger.error("Quantum connection failed, "
 
62
                          "no password or auth_token!")
 
63
             return None
 
64
-        logger.debug('quantum args %s', args)
 
65
+        logger.debug('neutron args %s', args)
 
66
 
 
67
-        self._quantum = quantumclient.Client(**args)
 
68
+        self._neutron = neutronclient.Client(**args)
 
69
 
 
70
-        return self._quantum
 
71
+        return self._neutron
 
72
 
 
73
     def cinder(self):
 
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):
 
79
     def swift(self):
 
80
         return self.stack.clients.swift()
 
81
 
 
82
-    def quantum(self):
 
83
-        return self.stack.clients.quantum()
 
84
+    def neutron(self):
 
85
+        return self.stack.clients.neutron()
 
86
 
 
87
     def cinder(self):
 
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):
 
93
         else:
 
94
             # if SubnetId property in Instance, ensure subnet exists
 
95
             if subnet_id:
 
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]
 
107
                     }
 
108
-                    port = quantumclient.create_port({'port': props})['port']
 
109
+                    port = neutronclient.create_port({'port': props})['port']
 
110
                     nics = [{'port-id': port['id']}]
 
111
 
 
112
         return nics
 
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)
 
118
 
 
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})
 
126
 
 
127
     def handle_delete(self):
 
128
-        from quantumclient.common.exceptions import QuantumClientException
 
129
+        from neutronclient.common.exceptions import NeutronClientException
 
130
 
 
131
-        client = self.quantum()
 
132
+        client = self.neutron()
 
133
         for router in self._vpc_route_tables():
 
134
             try:
 
135
                 client.remove_gateway_router(router.resource_id)
 
136
-            except QuantumClientException as ex:
 
137
+            except NeutronClientException as ex:
 
138
                 if ex.status_code != 404:
 
139
                     raise ex
 
140
 
 
141
 
 
142
 def resource_mapping():
 
143
-    if clients.quantumclient is None:
 
144
+    if clients.neutronclient is None:
 
145
         return {}
 
146
 
 
147
     return {
 
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
 
152
     }
 
153
 
 
154
     @staticmethod
 
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']
 
160
 
 
161
     def handle_create(self):
 
162
-        client = self.quantum()
 
163
+        client = self.neutron()
 
164
 
 
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'])
 
169
 
 
170
     def handle_delete(self):
 
171
-        from quantumclient.common.exceptions import QuantumClientException
 
172
+        from neutronclient.common.exceptions import NeutronClientException
 
173
 
 
174
-        client = self.quantum()
 
175
+        client = self.neutron()
 
176
         try:
 
177
             client.delete_port(self.resource_id)
 
178
-        except QuantumClientException as ex:
 
179
+        except NeutronClientException as ex:
 
180
             if ex.status_code != 404:
 
181
                 raise ex
 
182
 
 
183
 
 
184
 def resource_mapping():
 
185
-    if clients.quantumclient is None:
 
186
+    if clients.neutronclient is None:
 
187
         return {}
 
188
 
 
189
     return {
 
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
 
193
@@ -0,0 +1,110 @@
 
194
+# vim: tabstop=4 shiftwidth=4 softtabstop=4
 
195
+
 
196
+#
 
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
 
200
+#
 
201
+#         http://www.apache.org/licenses/LICENSE-2.0
 
202
+#
 
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.
 
208
+
 
209
+from heat.engine import clients
 
210
+from heat.openstack.common import log as logging
 
211
+from heat.engine.resources.neutron import neutron
 
212
+
 
213
+if clients.neutronclient is not None:
 
214
+    from neutronclient.common.exceptions import NeutronClientException
 
215
+
 
216
+logger = logging.getLogger(__name__)
 
217
+
 
218
+
 
219
+class FloatingIP(neutron.NeutronResource):
 
220
+    properties_schema = {'floating_network_id': {'Type': 'String',
 
221
+                                                 'Required': True},
 
222
+                         'value_specs': {'Type': 'Map',
 
223
+                                         'Default': {}},
 
224
+                         'port_id': {'Type': 'String'},
 
225
+                         'fixed_ip_address': {'Type': 'String'}}
 
226
+
 
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)
 
237
+
 
238
+    def handle_create(self):
 
239
+        props = self.prepare_properties(
 
240
+            self.properties,
 
241
+            self.physical_resource_name())
 
242
+        fip = self.neutron().create_floatingip({
 
243
+            'floatingip': props})['floatingip']
 
244
+        self.resource_id_set(fip['id'])
 
245
+
 
246
+    def handle_delete(self):
 
247
+        client = self.neutron()
 
248
+        try:
 
249
+            client.delete_floatingip(self.resource_id)
 
250
+        except NeutronClientException as ex:
 
251
+            if ex.status_code != 404:
 
252
+                raise ex
 
253
+
 
254
+    def FnGetAtt(self, key):
 
255
+        try:
 
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))
 
260
+            return None
 
261
+        return self.handle_get_attributes(self.name, key, attributes)
 
262
+
 
263
+
 
264
+class FloatingIPAssociation(neutron.NeutronResource):
 
265
+    properties_schema = {'floatingip_id': {'Type': 'String',
 
266
+                                           'Required': True},
 
267
+                         'port_id': {'Type': 'String',
 
268
+                                     'Required': True},
 
269
+                         'fixed_ip_address': {'Type': 'String'}}
 
270
+
 
271
+    def handle_create(self):
 
272
+        props = self.prepare_properties(self.properties, self.name)
 
273
+
 
274
+        floatingip_id = props.pop('floatingip_id')
 
275
+
 
276
+        self.neutron().update_floatingip(floatingip_id, {
 
277
+            'floatingip': props})['floatingip']
 
278
+        self.resource_id_set('%s:%s' % (floatingip_id, props['port_id']))
 
279
+
 
280
+    def handle_delete(self):
 
281
+        if not self.resource_id:
 
282
+            return
 
283
+        client = self.neutron()
 
284
+        (floatingip_id, port_id) = self.resource_id.split(':')
 
285
+        try:
 
286
+            client.update_floatingip(
 
287
+                floatingip_id,
 
288
+                {'floatingip': {'port_id': None}})
 
289
+        except NeutronClientException as ex:
 
290
+            if ex.status_code != 404:
 
291
+                raise ex
 
292
+
 
293
+
 
294
+def resource_mapping():
 
295
+    if clients.neutronclient is None:
 
296
+        return {}
 
297
+
 
298
+    return {
 
299
+        'OS::Neutron::FloatingIP': FloatingIP,
 
300
+        'OS::Neutron::FloatingIPAssociation': FloatingIPAssociation,
 
301
+        'OS::Quantum::FloatingIP': FloatingIP,
 
302
+        'OS::Quantum::FloatingIPAssociation': FloatingIPAssociation,
 
303
+    }
 
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
 
307
@@ -0,0 +1,75 @@
 
308
+# vim: tabstop=4 shiftwidth=4 softtabstop=4
 
309
+
 
310
+#
 
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
 
314
+#
 
315
+#         http://www.apache.org/licenses/LICENSE-2.0
 
316
+#
 
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.
 
322
+
 
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
 
327
+
 
328
+if clients.neutronclient is not None:
 
329
+    from neutronclient.common.exceptions import NeutronClientException
 
330
+
 
331
+logger = logging.getLogger(__name__)
 
332
+
 
333
+
 
334
+class Net(neutron.NeutronResource):
 
335
+    properties_schema = {'name': {'Type': 'String'},
 
336
+                         'value_specs': {'Type': 'Map',
 
337
+                                         'Default': {}},
 
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"
 
347
+    }
 
348
+
 
349
+    def handle_create(self):
 
350
+        props = self.prepare_properties(
 
351
+            self.properties,
 
352
+            self.physical_resource_name())
 
353
+        net = self.neutron().create_network({'network': props})['network']
 
354
+        self.resource_id_set(net['id'])
 
355
+
 
356
+    def _show_resource(self):
 
357
+        return self.neutron().show_network(
 
358
+            self.resource_id)['network']
 
359
+
 
360
+    def check_create_complete(self, *args):
 
361
+        attributes = self._show_resource()
 
362
+        return self.is_built(attributes)
 
363
+
 
364
+    def handle_delete(self):
 
365
+        client = self.neutron()
 
366
+        try:
 
367
+            client.delete_network(self.resource_id)
 
368
+        except NeutronClientException as ex:
 
369
+            if ex.status_code != 404:
 
370
+                raise ex
 
371
+        else:
 
372
+            return scheduler.TaskRunner(self._confirm_delete)()
 
373
+
 
374
+
 
375
+def resource_mapping():
 
376
+    if clients.neutronclient is None:
 
377
+        return {}
 
378
+
 
379
+    return {
 
380
+        'OS::Neutron::Net': Net,
 
381
+        'OS::Quantum::Net': Net,
 
382
+    }
 
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
 
386
@@ -0,0 +1,116 @@
 
387
+# vim: tabstop=4 shiftwidth=4 softtabstop=4
 
388
+
 
389
+#
 
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
 
393
+#
 
394
+#         http://www.apache.org/licenses/LICENSE-2.0
 
395
+#
 
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.
 
401
+
 
402
+from neutronclient.common.exceptions import NeutronClientException
 
403
+
 
404
+from heat.common import exception
 
405
+from heat.engine import resource
 
406
+
 
407
+from heat.openstack.common import log as logging
 
408
+
 
409
+logger = logging.getLogger(__name__)
 
410
+
 
411
+
 
412
+class NeutronResource(resource.Resource):
 
413
+
 
414
+    def validate(self):
 
415
+        '''
 
416
+        Validate any of the provided params
 
417
+        '''
 
418
+        res = super(NeutronResource, self).validate()
 
419
+        if res:
 
420
+            return res
 
421
+        return self.validate_properties(self.properties)
 
422
+
 
423
+    @staticmethod
 
424
+    def validate_properties(properties):
 
425
+        '''
 
426
+        Validates to ensure nothing in value_specs overwrites
 
427
+        any key that exists in the schema.
 
428
+
 
429
+        Also ensures that shared and tenant_id is not specified
 
430
+        in value_specs.
 
431
+        '''
 
432
+        if 'value_specs' in properties.keys():
 
433
+            vs = properties.get('value_specs')
 
434
+            banned_keys = set(['shared', 'tenant_id']).union(
 
435
+                properties.keys())
 
436
+            for k in banned_keys.intersection(vs.keys()):
 
437
+                return '%s not allowed in value_specs' % k
 
438
+
 
439
+    @staticmethod
 
440
+    def prepare_properties(properties, name):
 
441
+        '''
 
442
+        Prepares the property values so that they can be passed directly to
 
443
+        the Neutron call.
 
444
+
 
445
+        Removes None values and value_specs, merges value_specs with the main
 
446
+        values.
 
447
+        '''
 
448
+        props = dict((k, v) for k, v in properties.items()
 
449
+                     if v is not None and k != 'value_specs')
 
450
+
 
451
+        if 'name' in properties.keys():
 
452
+            props.setdefault('name', name)
 
453
+
 
454
+        if 'value_specs' in properties.keys():
 
455
+            props.update(properties.get('value_specs'))
 
456
+
 
457
+        return props
 
458
+
 
459
+    @staticmethod
 
460
+    def handle_get_attributes(name, key, attributes):
 
461
+        '''
 
462
+        Support method for responding to FnGetAtt
 
463
+        '''
 
464
+        if key == 'show':
 
465
+            return attributes
 
466
+
 
467
+        if key in attributes.keys():
 
468
+            return attributes[key]
 
469
+
 
470
+        raise exception.InvalidTemplateAttribute(resource=name, key=key)
 
471
+
 
472
+    @staticmethod
 
473
+    def is_built(attributes):
 
474
+        if attributes['status'] == 'BUILD':
 
475
+            return False
 
476
+        if attributes['status'] in ('ACTIVE', 'DOWN'):
 
477
+            return True
 
478
+        else:
 
479
+            raise exception.Error('%s resource[%s] status[%s]' %
 
480
+                                  ('neutron reported unexpected',
 
481
+                                   attributes['name'], attributes['status']))
 
482
+
 
483
+    def _resolve_attribute(self, name):
 
484
+        try:
 
485
+            attributes = self._show_resource()
 
486
+        except NeutronClientException as ex:
 
487
+            logger.warn("failed to fetch resource attributes: %s" % str(ex))
 
488
+            return None
 
489
+        return self.handle_get_attributes(self.name, name, attributes)
 
490
+
 
491
+    def _confirm_delete(self):
 
492
+        while True:
 
493
+            try:
 
494
+                yield
 
495
+                self._show_resource()
 
496
+            except NeutronClientException as ex:
 
497
+                if ex.status_code != 404:
 
498
+                    raise ex
 
499
+                return
 
500
+
 
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
 
506
@@ -0,0 +1,107 @@
 
507
+# vim: tabstop=4 shiftwidth=4 softtabstop=4
 
508
+
 
509
+#
 
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
 
513
+#
 
514
+#         http://www.apache.org/licenses/LICENSE-2.0
 
515
+#
 
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.
 
521
+
 
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
 
526
+
 
527
+if clients.neutronclient is not None:
 
528
+    from neutronclient.common.exceptions import NeutronClientException
 
529
+
 
530
+logger = logging.getLogger(__name__)
 
531
+
 
532
+
 
533
+class Port(neutron.NeutronResource):
 
534
+
 
535
+    fixed_ip_schema = {'subnet_id': {'Type': 'String',
 
536
+                                     'Required': True},
 
537
+                       'ip_address': {'Type': 'String'}}
 
538
+
 
539
+    properties_schema = {'network_id': {'Type': 'String',
 
540
+                                        'Required': True},
 
541
+                         'name': {'Type': 'String'},
 
542
+                         'value_specs': {'Type': 'Map',
 
543
+                                         'Default': {}},
 
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"
 
564
+    }
 
565
+
 
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)
 
579
+
 
580
+    def handle_create(self):
 
581
+        props = self.prepare_properties(
 
582
+            self.properties,
 
583
+            self.physical_resource_name())
 
584
+        port = self.neutron().create_port({'port': props})['port']
 
585
+        self.resource_id_set(port['id'])
 
586
+
 
587
+    def _show_resource(self):
 
588
+        return self.neutron().show_port(
 
589
+            self.resource_id)['port']
 
590
+
 
591
+    def check_create_complete(self, *args):
 
592
+        attributes = self._show_resource()
 
593
+        return self.is_built(attributes)
 
594
+
 
595
+    def handle_delete(self):
 
596
+        client = self.neutron()
 
597
+        try:
 
598
+            client.delete_port(self.resource_id)
 
599
+        except NeutronClientException as ex:
 
600
+            if ex.status_code != 404:
 
601
+                raise ex
 
602
+        else:
 
603
+            return scheduler.TaskRunner(self._confirm_delete)()
 
604
+
 
605
+
 
606
+def resource_mapping():
 
607
+    if clients.neutronclient is None:
 
608
+        return {}
 
609
+
 
610
+    return {
 
611
+        'OS::Neutron::Port': Port,
 
612
+        'OS::Quantum::Port': Port,
 
613
+    }
 
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
 
617
@@ -0,0 +1,149 @@
 
618
+# vim: tabstop=4 shiftwidth=4 softtabstop=4
 
619
+
 
620
+#
 
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
 
624
+#
 
625
+#         http://www.apache.org/licenses/LICENSE-2.0
 
626
+#
 
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.
 
632
+
 
633
+from heat.engine import clients
 
634
+from heat.engine.resources.neutron import neutron
 
635
+from heat.engine import scheduler
 
636
+
 
637
+if clients.neutronclient is not None:
 
638
+    from neutronclient.common.exceptions import NeutronClientException
 
639
+
 
640
+from heat.openstack.common import log as logging
 
641
+
 
642
+logger = logging.getLogger(__name__)
 
643
+
 
644
+
 
645
+class Router(neutron.NeutronResource):
 
646
+    properties_schema = {'name': {'Type': 'String'},
 
647
+                         'value_specs': {'Type': 'Map',
 
648
+                                         'Default': {}},
 
649
+                         'admin_state_up': {'Type': 'Boolean',
 
650
+                                            'Default': True}}
 
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"
 
658
+    }
 
659
+
 
660
+    def handle_create(self):
 
661
+        props = self.prepare_properties(
 
662
+            self.properties,
 
663
+            self.physical_resource_name())
 
664
+        router = self.neutron().create_router({'router': props})['router']
 
665
+        self.resource_id_set(router['id'])
 
666
+
 
667
+    def _show_resource(self):
 
668
+        return self.neutron().show_router(
 
669
+            self.resource_id)['router']
 
670
+
 
671
+    def check_create_complete(self, *args):
 
672
+        attributes = self._show_resource()
 
673
+        return self.is_built(attributes)
 
674
+
 
675
+    def handle_delete(self):
 
676
+        client = self.neutron()
 
677
+        try:
 
678
+            client.delete_router(self.resource_id)
 
679
+        except NeutronClientException as ex:
 
680
+            if ex.status_code != 404:
 
681
+                raise ex
 
682
+        else:
 
683
+            return scheduler.TaskRunner(self._confirm_delete)()
 
684
+
 
685
+
 
686
+class RouterInterface(neutron.NeutronResource):
 
687
+    properties_schema = {'router_id': {'Type': 'String',
 
688
+                                       'Required': True},
 
689
+                         'subnet_id': {'Type': 'String',
 
690
+                                       'Required': True}}
 
691
+
 
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(
 
696
+            router_id,
 
697
+            {'subnet_id': subnet_id})
 
698
+        self.resource_id_set('%s:%s' % (router_id, subnet_id))
 
699
+
 
700
+    def handle_delete(self):
 
701
+        client = self.neutron()
 
702
+        (router_id, subnet_id) = self.resource_id.split(':')
 
703
+        try:
 
704
+            client.remove_interface_router(
 
705
+                router_id,
 
706
+                {'subnet_id': subnet_id})
 
707
+        except NeutronClientException as ex:
 
708
+            if ex.status_code != 404:
 
709
+                raise ex
 
710
+
 
711
+
 
712
+class RouterGateway(neutron.NeutronResource):
 
713
+    properties_schema = {'router_id': {'Type': 'String',
 
714
+                                       'Required': True},
 
715
+                         'network_id': {'Type': 'String',
 
716
+                                        'Required': True}}
 
717
+
 
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
 
730
+            # on that subnet
 
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)
 
736
+
 
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(
 
741
+            router_id,
 
742
+            {'network_id': network_id})
 
743
+        self.resource_id_set('%s:%s' % (router_id, network_id))
 
744
+
 
745
+    def handle_delete(self):
 
746
+        client = self.neutron()
 
747
+        (router_id, network_id) = self.resource_id.split(':')
 
748
+        try:
 
749
+            client.remove_gateway_router(router_id)
 
750
+        except NeutronClientException as ex:
 
751
+            if ex.status_code != 404:
 
752
+                raise ex
 
753
+
 
754
+
 
755
+def resource_mapping():
 
756
+    if clients.neutronclient is None:
 
757
+        return {}
 
758
+
 
759
+    return {
 
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,
 
766
+    }
 
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
 
770
@@ -0,0 +1,95 @@
 
771
+# vim: tabstop=4 shiftwidth=4 softtabstop=4
 
772
+
 
773
+#
 
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
 
777
+#
 
778
+#         http://www.apache.org/licenses/LICENSE-2.0
 
779
+#
 
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.
 
785
+
 
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
 
790
+
 
791
+if clients.neutronclient is not None:
 
792
+    from neutronclient.common.exceptions import NeutronClientException
 
793
+
 
794
+logger = logging.getLogger(__name__)
 
795
+
 
796
+
 
797
+class Subnet(neutron.NeutronResource):
 
798
+
 
799
+    allocation_schema = {'start': {'Type': 'String',
 
800
+                                   'Required': True},
 
801
+                         'end': {'Type': 'String',
 
802
+                                 'Required': True}}
 
803
+
 
804
+    properties_schema = {'network_id': {'Type': 'String',
 
805
+                                        'Required': True},
 
806
+                         'cidr': {'Type': 'String',
 
807
+                                  'Required': True},
 
808
+                         'value_specs': {'Type': 'Map',
 
809
+                                         'Default': {}},
 
810
+                         'name': {'Type': 'String'},
 
811
+                         'ip_version': {'Type': 'Integer',
 
812
+                                        'AllowedValues': [4, 6],
 
813
+                                        'Default': 4},
 
814
+                         'dns_nameservers': {'Type': 'List'},
 
815
+                         'gateway_ip': {'Type': 'String'},
 
816
+                         'enable_dhcp': {'Type': 'Boolean'},
 
817
+                         'allocation_pools': {'Type': 'List',
 
818
+                                              'Schema': {
 
819
+                                              'Type': 'Map',
 
820
+                                              'Schema': allocation_schema
 
821
+                                              }}}
 
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'"
 
834
+                        "otherwise")
 
835
+    }
 
836
+
 
837
+    def handle_create(self):
 
838
+        props = self.prepare_properties(
 
839
+            self.properties,
 
840
+            self.physical_resource_name())
 
841
+        subnet = self.neutron().create_subnet({'subnet': props})['subnet']
 
842
+        self.resource_id_set(subnet['id'])
 
843
+
 
844
+    def handle_delete(self):
 
845
+        client = self.neutron()
 
846
+        try:
 
847
+            client.delete_subnet(self.resource_id)
 
848
+        except NeutronClientException as ex:
 
849
+            if ex.status_code != 404:
 
850
+                raise ex
 
851
+        else:
 
852
+            return scheduler.TaskRunner(self._confirm_delete)()
 
853
+
 
854
+    def _show_resource(self):
 
855
+        return self.neutron().show_subnet(self.resource_id)['subnet']
 
856
+
 
857
+
 
858
+def resource_mapping():
 
859
+    if clients.neutronclient is None:
 
860
+        return {}
 
861
+
 
862
+    return {
 
863
+        'OS::Neutron::Subnet': Subnet,
 
864
+        'OS::Quantum::Subnet': Subnet,
 
865
+    }
 
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
 
869
@@ -1,107 +0,0 @@
 
870
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
 
871
-
 
872
-#
 
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
 
876
-#
 
877
-#         http://www.apache.org/licenses/LICENSE-2.0
 
878
-#
 
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.
 
884
-
 
885
-from heat.engine import clients
 
886
-from heat.openstack.common import log as logging
 
887
-from heat.engine.resources.quantum import quantum
 
888
-
 
889
-if clients.quantumclient is not None:
 
890
-    from quantumclient.common.exceptions import QuantumClientException
 
891
-
 
892
-logger = logging.getLogger(__name__)
 
893
-
 
894
-
 
895
-class FloatingIP(quantum.QuantumResource):
 
896
-    properties_schema = {'floating_network_id': {'Type': 'String',
 
897
-                                                 'Required': True},
 
898
-                         'value_specs': {'Type': 'Map',
 
899
-                                         'Default': {}},
 
900
-                         'port_id': {'Type': 'String'},
 
901
-                         'fixed_ip_address': {'Type': 'String'}}
 
902
-
 
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)
 
912
-
 
913
-    def handle_create(self):
 
914
-        props = self.prepare_properties(
 
915
-            self.properties,
 
916
-            self.physical_resource_name())
 
917
-        fip = self.quantum().create_floatingip({
 
918
-            'floatingip': props})['floatingip']
 
919
-        self.resource_id_set(fip['id'])
 
920
-
 
921
-    def handle_delete(self):
 
922
-        client = self.quantum()
 
923
-        try:
 
924
-            client.delete_floatingip(self.resource_id)
 
925
-        except QuantumClientException as ex:
 
926
-            if ex.status_code != 404:
 
927
-                raise ex
 
928
-
 
929
-    def FnGetAtt(self, key):
 
930
-        try:
 
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))
 
935
-            return None
 
936
-        return self.handle_get_attributes(self.name, key, attributes)
 
937
-
 
938
-
 
939
-class FloatingIPAssociation(quantum.QuantumResource):
 
940
-    properties_schema = {'floatingip_id': {'Type': 'String',
 
941
-                                           'Required': True},
 
942
-                         'port_id': {'Type': 'String',
 
943
-                                     'Required': True},
 
944
-                         'fixed_ip_address': {'Type': 'String'}}
 
945
-
 
946
-    def handle_create(self):
 
947
-        props = self.prepare_properties(self.properties, self.name)
 
948
-
 
949
-        floatingip_id = props.pop('floatingip_id')
 
950
-
 
951
-        self.quantum().update_floatingip(floatingip_id, {
 
952
-            'floatingip': props})['floatingip']
 
953
-        self.resource_id_set('%s:%s' % (floatingip_id, props['port_id']))
 
954
-
 
955
-    def handle_delete(self):
 
956
-        if not self.resource_id:
 
957
-            return
 
958
-        client = self.quantum()
 
959
-        (floatingip_id, port_id) = self.resource_id.split(':')
 
960
-        try:
 
961
-            client.update_floatingip(
 
962
-                floatingip_id,
 
963
-                {'floatingip': {'port_id': None}})
 
964
-        except QuantumClientException as ex:
 
965
-            if ex.status_code != 404:
 
966
-                raise ex
 
967
-
 
968
-
 
969
-def resource_mapping():
 
970
-    if clients.quantumclient is None:
 
971
-        return {}
 
972
-
 
973
-    return {
 
974
-        'OS::Quantum::FloatingIP': FloatingIP,
 
975
-        'OS::Quantum::FloatingIPAssociation': FloatingIPAssociation,
 
976
-    }
 
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
 
980
@@ -1,74 +0,0 @@
 
981
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
 
982
-
 
983
-#
 
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
 
987
-#
 
988
-#         http://www.apache.org/licenses/LICENSE-2.0
 
989
-#
 
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.
 
995
-
 
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
 
1000
-
 
1001
-if clients.quantumclient is not None:
 
1002
-    from quantumclient.common.exceptions import QuantumClientException
 
1003
-
 
1004
-logger = logging.getLogger(__name__)
 
1005
-
 
1006
-
 
1007
-class Net(quantum.QuantumResource):
 
1008
-    properties_schema = {'name': {'Type': 'String'},
 
1009
-                         'value_specs': {'Type': 'Map',
 
1010
-                                         'Default': {}},
 
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"
 
1020
-    }
 
1021
-
 
1022
-    def handle_create(self):
 
1023
-        props = self.prepare_properties(
 
1024
-            self.properties,
 
1025
-            self.physical_resource_name())
 
1026
-        net = self.quantum().create_network({'network': props})['network']
 
1027
-        self.resource_id_set(net['id'])
 
1028
-
 
1029
-    def _show_resource(self):
 
1030
-        return self.quantum().show_network(
 
1031
-            self.resource_id)['network']
 
1032
-
 
1033
-    def check_create_complete(self, *args):
 
1034
-        attributes = self._show_resource()
 
1035
-        return self.is_built(attributes)
 
1036
-
 
1037
-    def handle_delete(self):
 
1038
-        client = self.quantum()
 
1039
-        try:
 
1040
-            client.delete_network(self.resource_id)
 
1041
-        except QuantumClientException as ex:
 
1042
-            if ex.status_code != 404:
 
1043
-                raise ex
 
1044
-        else:
 
1045
-            return scheduler.TaskRunner(self._confirm_delete)()
 
1046
-
 
1047
-
 
1048
-def resource_mapping():
 
1049
-    if clients.quantumclient is None:
 
1050
-        return {}
 
1051
-
 
1052
-    return {
 
1053
-        'OS::Quantum::Net': Net,
 
1054
-    }
 
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
 
1058
@@ -1,105 +0,0 @@
 
1059
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
 
1060
-
 
1061
-#
 
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
 
1065
-#
 
1066
-#         http://www.apache.org/licenses/LICENSE-2.0
 
1067
-#
 
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.
 
1073
-
 
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
 
1078
-
 
1079
-if clients.quantumclient is not None:
 
1080
-    from quantumclient.common.exceptions import QuantumClientException
 
1081
-
 
1082
-logger = logging.getLogger(__name__)
 
1083
-
 
1084
-
 
1085
-class Port(quantum.QuantumResource):
 
1086
-
 
1087
-    fixed_ip_schema = {'subnet_id': {'Type': 'String',
 
1088
-                                     'Required': True},
 
1089
-                       'ip_address': {'Type': 'String'}}
 
1090
-
 
1091
-    properties_schema = {'network_id': {'Type': 'String',
 
1092
-                                        'Required': True},
 
1093
-                         'name': {'Type': 'String'},
 
1094
-                         'value_specs': {'Type': 'Map',
 
1095
-                                         'Default': {}},
 
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"
 
1116
-    }
 
1117
-
 
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)
 
1130
-
 
1131
-    def handle_create(self):
 
1132
-        props = self.prepare_properties(
 
1133
-            self.properties,
 
1134
-            self.physical_resource_name())
 
1135
-        port = self.quantum().create_port({'port': props})['port']
 
1136
-        self.resource_id_set(port['id'])
 
1137
-
 
1138
-    def _show_resource(self):
 
1139
-        return self.quantum().show_port(
 
1140
-            self.resource_id)['port']
 
1141
-
 
1142
-    def check_create_complete(self, *args):
 
1143
-        attributes = self._show_resource()
 
1144
-        return self.is_built(attributes)
 
1145
-
 
1146
-    def handle_delete(self):
 
1147
-        client = self.quantum()
 
1148
-        try:
 
1149
-            client.delete_port(self.resource_id)
 
1150
-        except QuantumClientException as ex:
 
1151
-            if ex.status_code != 404:
 
1152
-                raise ex
 
1153
-        else:
 
1154
-            return scheduler.TaskRunner(self._confirm_delete)()
 
1155
-
 
1156
-
 
1157
-def resource_mapping():
 
1158
-    if clients.quantumclient is None:
 
1159
-        return {}
 
1160
-
 
1161
-    return {
 
1162
-        'OS::Quantum::Port': Port,
 
1163
-    }
 
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
 
1167
@@ -1,116 +0,0 @@
 
1168
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
 
1169
-
 
1170
-#
 
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
 
1174
-#
 
1175
-#         http://www.apache.org/licenses/LICENSE-2.0
 
1176
-#
 
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.
 
1182
-
 
1183
-from quantumclient.common.exceptions import QuantumClientException
 
1184
-
 
1185
-from heat.common import exception
 
1186
-from heat.engine import resource
 
1187
-
 
1188
-from heat.openstack.common import log as logging
 
1189
-
 
1190
-logger = logging.getLogger(__name__)
 
1191
-
 
1192
-
 
1193
-class QuantumResource(resource.Resource):
 
1194
-
 
1195
-    def validate(self):
 
1196
-        '''
 
1197
-        Validate any of the provided params
 
1198
-        '''
 
1199
-        res = super(QuantumResource, self).validate()
 
1200
-        if res:
 
1201
-            return res
 
1202
-        return self.validate_properties(self.properties)
 
1203
-
 
1204
-    @staticmethod
 
1205
-    def validate_properties(properties):
 
1206
-        '''
 
1207
-        Validates to ensure nothing in value_specs overwrites
 
1208
-        any key that exists in the schema.
 
1209
-
 
1210
-        Also ensures that shared and tenant_id is not specified
 
1211
-        in value_specs.
 
1212
-        '''
 
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
 
1219
-
 
1220
-    @staticmethod
 
1221
-    def prepare_properties(properties, name):
 
1222
-        '''
 
1223
-        Prepares the property values so that they can be passed directly to
 
1224
-        the Quantum call.
 
1225
-
 
1226
-        Removes None values and value_specs, merges value_specs with the main
 
1227
-        values.
 
1228
-        '''
 
1229
-        props = dict((k, v) for k, v in properties.items()
 
1230
-                     if v is not None and k != 'value_specs')
 
1231
-
 
1232
-        if 'name' in properties.keys():
 
1233
-            props.setdefault('name', name)
 
1234
-
 
1235
-        if 'value_specs' in properties.keys():
 
1236
-            props.update(properties.get('value_specs'))
 
1237
-
 
1238
-        return props
 
1239
-
 
1240
-    @staticmethod
 
1241
-    def handle_get_attributes(name, key, attributes):
 
1242
-        '''
 
1243
-        Support method for responding to FnGetAtt
 
1244
-        '''
 
1245
-        if key == 'show':
 
1246
-            return attributes
 
1247
-
 
1248
-        if key in attributes.keys():
 
1249
-            return attributes[key]
 
1250
-
 
1251
-        raise exception.InvalidTemplateAttribute(resource=name, key=key)
 
1252
-
 
1253
-    @staticmethod
 
1254
-    def is_built(attributes):
 
1255
-        if attributes['status'] == 'BUILD':
 
1256
-            return False
 
1257
-        if attributes['status'] in ('ACTIVE', 'DOWN'):
 
1258
-            return True
 
1259
-        else:
 
1260
-            raise exception.Error('%s resource[%s] status[%s]' %
 
1261
-                                  ('quantum reported unexpected',
 
1262
-                                   attributes['name'], attributes['status']))
 
1263
-
 
1264
-    def _resolve_attribute(self, name):
 
1265
-        try:
 
1266
-            attributes = self._show_resource()
 
1267
-        except QuantumClientException as ex:
 
1268
-            logger.warn("failed to fetch resource attributes: %s" % str(ex))
 
1269
-            return None
 
1270
-        return self.handle_get_attributes(self.name, name, attributes)
 
1271
-
 
1272
-    def _confirm_delete(self):
 
1273
-        while True:
 
1274
-            try:
 
1275
-                yield
 
1276
-                self._show_resource()
 
1277
-            except QuantumClientException as ex:
 
1278
-                if ex.status_code != 404:
 
1279
-                    raise ex
 
1280
-                return
 
1281
-
 
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
 
1287
@@ -1,144 +0,0 @@
 
1288
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
 
1289
-
 
1290
-#
 
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
 
1294
-#
 
1295
-#         http://www.apache.org/licenses/LICENSE-2.0
 
1296
-#
 
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.
 
1302
-
 
1303
-from heat.engine import clients
 
1304
-from heat.engine.resources.quantum import quantum
 
1305
-from heat.engine import scheduler
 
1306
-
 
1307
-if clients.quantumclient is not None:
 
1308
-    from quantumclient.common.exceptions import QuantumClientException
 
1309
-
 
1310
-from heat.openstack.common import log as logging
 
1311
-
 
1312
-logger = logging.getLogger(__name__)
 
1313
-
 
1314
-
 
1315
-class Router(quantum.QuantumResource):
 
1316
-    properties_schema = {'name': {'Type': 'String'},
 
1317
-                         'value_specs': {'Type': 'Map',
 
1318
-                                         'Default': {}},
 
1319
-                         'admin_state_up': {'Type': 'Boolean',
 
1320
-                                            'Default': True}}
 
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"
 
1328
-    }
 
1329
-
 
1330
-    def handle_create(self):
 
1331
-        props = self.prepare_properties(
 
1332
-            self.properties,
 
1333
-            self.physical_resource_name())
 
1334
-        router = self.quantum().create_router({'router': props})['router']
 
1335
-        self.resource_id_set(router['id'])
 
1336
-
 
1337
-    def _show_resource(self):
 
1338
-        return self.quantum().show_router(
 
1339
-            self.resource_id)['router']
 
1340
-
 
1341
-    def check_create_complete(self, *args):
 
1342
-        attributes = self._show_resource()
 
1343
-        return self.is_built(attributes)
 
1344
-
 
1345
-    def handle_delete(self):
 
1346
-        client = self.quantum()
 
1347
-        try:
 
1348
-            client.delete_router(self.resource_id)
 
1349
-        except QuantumClientException as ex:
 
1350
-            if ex.status_code != 404:
 
1351
-                raise ex
 
1352
-        else:
 
1353
-            return scheduler.TaskRunner(self._confirm_delete)()
 
1354
-
 
1355
-
 
1356
-class RouterInterface(quantum.QuantumResource):
 
1357
-    properties_schema = {'router_id': {'Type': 'String',
 
1358
-                                       'Required': True},
 
1359
-                         'subnet_id': {'Type': 'String',
 
1360
-                                       'Required': True}}
 
1361
-
 
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(
 
1366
-            router_id,
 
1367
-            {'subnet_id': subnet_id})
 
1368
-        self.resource_id_set('%s:%s' % (router_id, subnet_id))
 
1369
-
 
1370
-    def handle_delete(self):
 
1371
-        client = self.quantum()
 
1372
-        (router_id, subnet_id) = self.resource_id.split(':')
 
1373
-        try:
 
1374
-            client.remove_interface_router(
 
1375
-                router_id,
 
1376
-                {'subnet_id': subnet_id})
 
1377
-        except QuantumClientException as ex:
 
1378
-            if ex.status_code != 404:
 
1379
-                raise ex
 
1380
-
 
1381
-
 
1382
-class RouterGateway(quantum.QuantumResource):
 
1383
-    properties_schema = {'router_id': {'Type': 'String',
 
1384
-                                       'Required': True},
 
1385
-                         'network_id': {'Type': 'String',
 
1386
-                                        'Required': True}}
 
1387
-
 
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
 
1399
-            # on that subnet
 
1400
-            elif (resource.type() == 'OS::Quantum::Subnet' and
 
1401
-                  resource.properties.get('network_id') ==
 
1402
-                    self.properties.get('network_id')):
 
1403
-                        deps += (self, resource)
 
1404
-
 
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(
 
1409
-            router_id,
 
1410
-            {'network_id': network_id})
 
1411
-        self.resource_id_set('%s:%s' % (router_id, network_id))
 
1412
-
 
1413
-    def handle_delete(self):
 
1414
-        client = self.quantum()
 
1415
-        (router_id, network_id) = self.resource_id.split(':')
 
1416
-        try:
 
1417
-            client.remove_gateway_router(router_id)
 
1418
-        except QuantumClientException as ex:
 
1419
-            if ex.status_code != 404:
 
1420
-                raise ex
 
1421
-
 
1422
-
 
1423
-def resource_mapping():
 
1424
-    if clients.quantumclient is None:
 
1425
-        return {}
 
1426
-
 
1427
-    return {
 
1428
-        'OS::Quantum::Router': Router,
 
1429
-        'OS::Quantum::RouterInterface': RouterInterface,
 
1430
-        'OS::Quantum::RouterGateway': RouterGateway,
 
1431
-    }
 
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
 
1435
@@ -1,94 +0,0 @@
 
1436
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
 
1437
-
 
1438
-#
 
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
 
1442
-#
 
1443
-#         http://www.apache.org/licenses/LICENSE-2.0
 
1444
-#
 
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.
 
1450
-
 
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
 
1455
-
 
1456
-if clients.quantumclient is not None:
 
1457
-    from quantumclient.common.exceptions import QuantumClientException
 
1458
-
 
1459
-logger = logging.getLogger(__name__)
 
1460
-
 
1461
-
 
1462
-class Subnet(quantum.QuantumResource):
 
1463
-
 
1464
-    allocation_schema = {'start': {'Type': 'String',
 
1465
-                                   'Required': True},
 
1466
-                         'end': {'Type': 'String',
 
1467
-                                 'Required': True}}
 
1468
-
 
1469
-    properties_schema = {'network_id': {'Type': 'String',
 
1470
-                                        'Required': True},
 
1471
-                         'cidr': {'Type': 'String',
 
1472
-                                  'Required': True},
 
1473
-                         'value_specs': {'Type': 'Map',
 
1474
-                                         'Default': {}},
 
1475
-                         'name': {'Type': 'String'},
 
1476
-                         'ip_version': {'Type': 'Integer',
 
1477
-                                        'AllowedValues': [4, 6],
 
1478
-                                        'Default': 4},
 
1479
-                         'dns_nameservers': {'Type': 'List'},
 
1480
-                         'gateway_ip': {'Type': 'String'},
 
1481
-                         'enable_dhcp': {'Type': 'Boolean'},
 
1482
-                         'allocation_pools': {'Type': 'List',
 
1483
-                                              'Schema': {
 
1484
-                                              'Type': 'Map',
 
1485
-                                              'Schema': allocation_schema
 
1486
-                                              }}}
 
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'"
 
1499
-                        "otherwise")
 
1500
-    }
 
1501
-
 
1502
-    def handle_create(self):
 
1503
-        props = self.prepare_properties(
 
1504
-            self.properties,
 
1505
-            self.physical_resource_name())
 
1506
-        subnet = self.quantum().create_subnet({'subnet': props})['subnet']
 
1507
-        self.resource_id_set(subnet['id'])
 
1508
-
 
1509
-    def handle_delete(self):
 
1510
-        client = self.quantum()
 
1511
-        try:
 
1512
-            client.delete_subnet(self.resource_id)
 
1513
-        except QuantumClientException as ex:
 
1514
-            if ex.status_code != 404:
 
1515
-                raise ex
 
1516
-        else:
 
1517
-            return scheduler.TaskRunner(self._confirm_delete)()
 
1518
-
 
1519
-    def _show_resource(self):
 
1520
-        return self.quantum().show_subnet(self.resource_id)['subnet']
 
1521
-
 
1522
-
 
1523
-def resource_mapping():
 
1524
-    if clients.quantumclient is None:
 
1525
-        return {}
 
1526
-
 
1527
-    return {
 
1528
-        'OS::Quantum::Subnet': Subnet,
 
1529
-    }
 
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
 
1534
 
 
1535
         return self._cloud_blockstore
 
1536
 
 
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
 
1547
@@ -16,11 +16,11 @@
 
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
 
1554
 
 
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
 
1559
 
 
1560
 logger = logging.getLogger(__name__)
 
1561
 
 
1562
@@ -42,16 +42,16 @@ class RouteTable(resource.Resource):
 
1563
     }
 
1564
 
 
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'])
 
1571
 
 
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):
 
1579
             return False
 
1580
 
 
1581
         network_id = self.properties.get('VpcId')
 
1582
@@ -66,19 +66,19 @@ class RouteTable(resource.Resource):
 
1583
         return True
 
1584
 
 
1585
     def handle_delete(self):
 
1586
-        client = self.quantum()
 
1587
+        client = self.neutron()
 
1588
 
 
1589
         router_id = self.resource_id
 
1590
         try:
 
1591
             client.delete_router(router_id)
 
1592
-        except QuantumClientException as ex:
 
1593
+        except NeutronClientException as ex:
 
1594
             if ex.status_code != 404:
 
1595
                 raise ex
 
1596
 
 
1597
         # just in case this router has been added to a gateway, remove it
 
1598
         try:
 
1599
             client.remove_gateway_router(router_id)
 
1600
-        except QuantumClientException as ex:
 
1601
+        except NeutronClientException as ex:
 
1602
             if ex.status_code != 404:
 
1603
                 raise ex
 
1604
 
 
1605
@@ -95,7 +95,7 @@ class SubnetRouteTableAssocation(resourc
 
1606
     }
 
1607
 
 
1608
     def handle_create(self):
 
1609
-        client = self.quantum()
 
1610
+        client = self.neutron()
 
1611
         subnet_id = self.properties.get('SubnetId')
 
1612
 
 
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:
 
1621
                 raise ex
 
1622
 
 
1623
@@ -115,14 +115,14 @@ class SubnetRouteTableAssocation(resourc
 
1624
             router_id, {'subnet_id': subnet_id})
 
1625
 
 
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)
 
1633
 
 
1634
     def handle_delete(self):
 
1635
-        client = self.quantum()
 
1636
+        client = self.neutron()
 
1637
         subnet_id = self.properties.get('SubnetId')
 
1638
 
 
1639
         router_id = self.properties.get('RouteTableId')
 
1640
@@ -130,7 +130,7 @@ class SubnetRouteTableAssocation(resourc
 
1641
         try:
 
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:
 
1647
                 raise ex
 
1648
 
 
1649
@@ -140,13 +140,13 @@ class SubnetRouteTableAssocation(resourc
 
1650
             if default_router:
 
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:
 
1656
                 raise ex
 
1657
 
 
1658
 
 
1659
 def resource_mapping():
 
1660
-    if clients.quantumclient is None:
 
1661
+    if clients.neutronclient is None:
 
1662
         return {}
 
1663
 
 
1664
     return {
 
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'}}
 
1670
 
 
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()
 
1676
         else:
 
1677
             self._handle_create_nova()
 
1678
 
 
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()
 
1685
 
 
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']
 
1699
                         }
 
1700
                     })
 
1701
-                except QuantumClientException as ex:
 
1702
+                except NeutronClientException as ex:
 
1703
                     if ex.status_code == 409:
 
1704
                         # no worries, the rule is already there
 
1705
                         pass
 
1706
@@ -87,7 +87,7 @@ class SecurityGroup(resource.Resource):
 
1707
                             'security_group_id': sec['id']
 
1708
                         }
 
1709
                     })
 
1710
-                except QuantumClientException as ex:
 
1711
+                except NeutronClientException as ex:
 
1712
                     if ex.status_code == 409:
 
1713
                         # no worries, the rule is already there
 
1714
                         pass
 
1715
@@ -128,8 +128,8 @@ class SecurityGroup(resource.Resource):
 
1716
                         raise
 
1717
 
 
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()
 
1723
         else:
 
1724
             self._handle_delete_nova()
 
1725
 
 
1726
@@ -149,28 +149,28 @@ class SecurityGroup(resource.Resource):
 
1727
                 self.nova().security_groups.delete(self.resource_id)
 
1728
             self.resource_id = None
 
1729
 
 
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()
 
1736
 
 
1737
         if self.resource_id is not None:
 
1738
             try:
 
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:
 
1744
                     raise
 
1745
             else:
 
1746
                 for rule in sec['security_group_rules']:
 
1747
                     try:
 
1748
                         client.delete_security_group_rule(rule['id'])
 
1749
-                    except QuantumClientException as ex:
 
1750
+                    except NeutronClientException as ex:
 
1751
                         if ex.status_code != 404:
 
1752
                             raise
 
1753
 
 
1754
                 try:
 
1755
                     client.delete_security_group(self.resource_id)
 
1756
-                except QuantumClientException as ex:
 
1757
+                except NeutronClientException as ex:
 
1758
                     if ex.status_code != 404:
 
1759
                         raise
 
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):
 
1765
     }
 
1766
 
 
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')
 
1772
 
 
1773
@@ -55,7 +55,7 @@ class Subnet(resource.Resource):
 
1774
         }
 
1775
         subnet = client.create_subnet({'subnet': props})['subnet']
 
1776
 
 
1777
-        router = VPC.router_for_vpc(self.quantum(), network_id)
 
1778
+        router = VPC.router_for_vpc(self.neutron(), network_id)
 
1779
         if router:
 
1780
             client.add_interface_router(
 
1781
                 router['id'],
 
1782
@@ -63,25 +63,25 @@ class Subnet(resource.Resource):
 
1783
         self.resource_id_set(subnet['id'])
 
1784
 
 
1785
     def handle_delete(self):
 
1786
-        from quantumclient.common.exceptions import QuantumClientException
 
1787
+        from neutronclient.common.exceptions import NeutronClientException
 
1788
 
 
1789
-        client = self.quantum()
 
1790
+        client = self.neutron()
 
1791
         network_id = self.properties.get('VpcId')
 
1792
         subnet_id = self.resource_id
 
1793
 
 
1794
         try:
 
1795
-            router = VPC.router_for_vpc(self.quantum(), network_id)
 
1796
+            router = VPC.router_for_vpc(self.neutron(), network_id)
 
1797
             if router:
 
1798
                 client.remove_interface_router(
 
1799
                     router['id'],
 
1800
                     {'subnet_id': subnet_id})
 
1801
-        except QuantumClientException as ex:
 
1802
+        except NeutronClientException as ex:
 
1803
             if ex.status_code != 404:
 
1804
                 raise ex
 
1805
 
 
1806
         try:
 
1807
             client.delete_subnet(subnet_id)
 
1808
-        except QuantumClientException as ex:
 
1809
+        except NeutronClientException as ex:
 
1810
             if ex.status_code != 404:
 
1811
                 raise ex
 
1812
 
 
1813
@@ -92,7 +92,7 @@ class Subnet(resource.Resource):
 
1814
 
 
1815
 
 
1816
 def resource_mapping():
 
1817
-    if clients.quantumclient is None:
 
1818
+    if clients.neutronclient is None:
 
1819
         return {}
 
1820
 
 
1821
     return {
 
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
 
1831
 
 
1832
 logger = logging.getLogger(__name__)
 
1833
 
 
1834
@@ -43,7 +43,7 @@ class VPC(resource.Resource):
 
1835
     }
 
1836
 
 
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):
 
1844
 
 
1845
     @staticmethod
 
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):
 
1853
         return routers[0]
 
1854
 
 
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):
 
1860
             return False
 
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)
 
1865
 
 
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)
 
1872
         try:
 
1873
             client.delete_router(router['id'])
 
1874
-        except QuantumClientException as ex:
 
1875
+        except NeutronClientException as ex:
 
1876
             if ex.status_code != 404:
 
1877
                 raise ex
 
1878
 
 
1879
         try:
 
1880
             client.delete_network(self.resource_id)
 
1881
-        except QuantumClientException as ex:
 
1882
+        except NeutronClientException as ex:
 
1883
             if ex.status_code != 404:
 
1884
                 raise ex
 
1885
 
 
1886
 
 
1887
 def resource_mapping():
 
1888
-    if clients.quantumclient is None:
 
1889
+    if clients.neutronclient is None:
 
1890
         return {}
 
1891
 
 
1892
     return {
 
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
 
1896
@@ -0,0 +1,100 @@
 
1897
+{
 
1898
+  "AWSTemplateFormatVersion" : "2010-09-09",
 
1899
+
 
1900
+  "Description" : "Template to test Neutron resources",
 
1901
+
 
1902
+  "Parameters" : {
 
1903
+
 
1904
+  },
 
1905
+
 
1906
+  "Resources" : {
 
1907
+    "network": {
 
1908
+      "Type": "OS::Neutron::Net",
 
1909
+      "Properties": {
 
1910
+        "name": "the_network"
 
1911
+      }
 
1912
+    },
 
1913
+    "unnamed_network": {
 
1914
+      "Type": "OS::Neutron::Net"
 
1915
+    },
 
1916
+    "admin_down_network": {
 
1917
+      "Type": "OS::Neutron::Net",
 
1918
+      "Properties": {
 
1919
+        "admin_state_up": false
 
1920
+      }
 
1921
+    },
 
1922
+
 
1923
+    "subnet": {
 
1924
+      "Type": "OS::Neutron::Subnet",
 
1925
+      "Properties": {
 
1926
+        "network_id": { "Ref" : "network" },
 
1927
+        "ip_version": 4,
 
1928
+        "cidr": "10.0.3.0/24",
 
1929
+        "allocation_pools": [{"start": "10.0.3.20", "end": "10.0.3.150"}]
 
1930
+      }
 
1931
+    },
 
1932
+
 
1933
+    "port": {
 
1934
+      "Type": "OS::Neutron::Port",
 
1935
+      "Properties": {
 
1936
+        "device_id": "d6b4d3a5-c700-476f-b609-1493dd9dadc0",
 
1937
+        "name": "port1",
 
1938
+        "network_id": { "Ref" : "network" },
 
1939
+        "fixed_ips": [{
 
1940
+          "subnet_id": { "Ref" : "subnet" },
 
1941
+          "ip_address": "10.0.3.21"
 
1942
+        }]
 
1943
+      }
 
1944
+    },
 
1945
+
 
1946
+    "router": {
 
1947
+      "Type": "OS::Neutron::Router"
 
1948
+    },
 
1949
+
 
1950
+    "router_interface": {
 
1951
+      "Type": "OS::Neutron::RouterInterface",
 
1952
+      "Properties": {
 
1953
+        "router_id": { "Ref" : "router" },
 
1954
+        "subnet_id": { "Ref" : "subnet" }
 
1955
+      }
 
1956
+    }
 
1957
+  },
 
1958
+  "Outputs" : {
 
1959
+    "the_network_status" : {
 
1960
+      "Value" : { "Fn::GetAtt" : [ "network", "status" ]},
 
1961
+      "Description" : "Status of network"
 
1962
+    },
 
1963
+    "port_device_owner" : {
 
1964
+      "Value" : { "Fn::GetAtt" : [ "port", "device_owner" ]},
 
1965
+      "Description" : "Device owner of the port"
 
1966
+    },
 
1967
+    "port_fixed_ips" : {
 
1968
+      "Value" : { "Fn::GetAtt" : [ "port", "fixed_ips" ]},
 
1969
+      "Description" : "Fixed IPs of the port"
 
1970
+    },
 
1971
+    "port_mac_address" : {
 
1972
+      "Value" : { "Fn::GetAtt" : [ "port", "mac_address" ]},
 
1973
+      "Description" : "MAC address of the port"
 
1974
+    },
 
1975
+    "port_status" : {
 
1976
+      "Value" : { "Fn::GetAtt" : [ "port", "status" ]},
 
1977
+      "Description" : "Status of the port"
 
1978
+    },
 
1979
+    "port_show" : {
 
1980
+      "Value" : { "Fn::GetAtt" : [ "port", "show" ]},
 
1981
+      "Description" : "All attributes for port"
 
1982
+    },
 
1983
+    "subnet_show" : {
 
1984
+      "Value" : { "Fn::GetAtt" : [ "subnet", "show" ]},
 
1985
+      "Description" : "All attributes for subnet"
 
1986
+    },
 
1987
+    "network_show" : {
 
1988
+      "Value" : { "Fn::GetAtt" : [ "network", "show" ]},
 
1989
+      "Description" : "All attributes for network"
 
1990
+    },
 
1991
+    "router_show" : {
 
1992
+      "Value" : { "Fn::GetAtt" : [ "router", "show" ]},
 
1993
+      "Description" : "All attributes for router"
 
1994
+    }
 
1995
+  }
 
1996
+}
 
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
 
2000
@@ -0,0 +1,72 @@
 
2001
+HeatTemplateFormatVersion: '2012-12-12'
 
2002
+Description: Template to test Neutron resources
 
2003
+Resources:
 
2004
+  network:
 
2005
+    Type: OS::Neutron::Net
 
2006
+    Properties: {name: the_network}
 
2007
+  unnamed_network:
 
2008
+    Type: 'OS::Neutron::Net'
 
2009
+  admin_down_network:
 
2010
+    Type: OS::Neutron::Net
 
2011
+    Properties: {admin_state_up: false}
 
2012
+  subnet:
 
2013
+    Type: OS::Neutron::Subnet
 
2014
+    Properties:
 
2015
+      network_id: {Ref: network}
 
2016
+      ip_version: 4
 
2017
+      cidr: 10.0.3.0/24
 
2018
+      allocation_pools:
 
2019
+      - {end: 10.0.3.150, start: 10.0.3.20}
 
2020
+  port:
 
2021
+    Type: OS::Neutron::Port
 
2022
+    Properties:
 
2023
+      device_id: d6b4d3a5-c700-476f-b609-1493dd9dadc0
 
2024
+      name: port1
 
2025
+      network_id: {Ref: network}
 
2026
+      fixed_ips:
 
2027
+      - subnet_id: {Ref: subnet}
 
2028
+        ip_address: 10.0.3.21
 
2029
+  router:
 
2030
+    Type: 'OS::Neutron::Router'
 
2031
+  router_interface:
 
2032
+    Type: OS::Neutron::RouterInterface
 
2033
+    Properties:
 
2034
+      router_id: {Ref: router}
 
2035
+      subnet_id: {Ref: subnet}
 
2036
+Outputs:
 
2037
+  the_network_status:
 
2038
+    Value:
 
2039
+      Fn::GetAtt: [network, status]
 
2040
+    Description: Status of network
 
2041
+  port_device_owner:
 
2042
+    Value:
 
2043
+      Fn::GetAtt: [port, device_owner]
 
2044
+    Description: Device owner of the port
 
2045
+  port_fixed_ips:
 
2046
+    Value:
 
2047
+      Fn::GetAtt: [port, fixed_ips]
 
2048
+    Description: Fixed IPs of the port
 
2049
+  port_mac_address:
 
2050
+    Value:
 
2051
+      Fn::GetAtt: [port, mac_address]
 
2052
+    Description: MAC address of the port
 
2053
+  port_status:
 
2054
+    Value:
 
2055
+      Fn::GetAtt: [port, status]
 
2056
+    Description: Status of the port
 
2057
+  port_show:
 
2058
+    Value:
 
2059
+      Fn::GetAtt: [port, show]
 
2060
+    Description: All attributes for port
 
2061
+  subnet_show:
 
2062
+    Value:
 
2063
+      Fn::GetAtt: [subnet, show]
 
2064
+    Description: All attributes for subnet
 
2065
+  network_show:
 
2066
+    Value:
 
2067
+      Fn::GetAtt: [network, show]
 
2068
+    Description: All attributes for network
 
2069
+  router_show:
 
2070
+    Value:
 
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
 
2076
@@ -1,100 +0,0 @@
 
2077
-{
 
2078
-  "AWSTemplateFormatVersion" : "2010-09-09",
 
2079
-
 
2080
-  "Description" : "Template to test Quantum resources",
 
2081
-
 
2082
-  "Parameters" : {
 
2083
-
 
2084
-  },
 
2085
-
 
2086
-  "Resources" : {
 
2087
-    "network": {
 
2088
-      "Type": "OS::Quantum::Net",
 
2089
-      "Properties": {
 
2090
-        "name": "the_network"
 
2091
-      }
 
2092
-    },
 
2093
-    "unnamed_network": {
 
2094
-      "Type": "OS::Quantum::Net"
 
2095
-    },
 
2096
-    "admin_down_network": {
 
2097
-      "Type": "OS::Quantum::Net",
 
2098
-      "Properties": {
 
2099
-        "admin_state_up": false
 
2100
-      }
 
2101
-    },
 
2102
-
 
2103
-    "subnet": {
 
2104
-      "Type": "OS::Quantum::Subnet",
 
2105
-      "Properties": {
 
2106
-        "network_id": { "Ref" : "network" },
 
2107
-        "ip_version": 4,
 
2108
-        "cidr": "10.0.3.0/24",
 
2109
-        "allocation_pools": [{"start": "10.0.3.20", "end": "10.0.3.150"}]
 
2110
-      }
 
2111
-    },
 
2112
-
 
2113
-    "port": {
 
2114
-      "Type": "OS::Quantum::Port",
 
2115
-      "Properties": {
 
2116
-        "device_id": "d6b4d3a5-c700-476f-b609-1493dd9dadc0",
 
2117
-        "name": "port1",
 
2118
-        "network_id": { "Ref" : "network" },
 
2119
-        "fixed_ips": [{
 
2120
-          "subnet_id": { "Ref" : "subnet" },
 
2121
-          "ip_address": "10.0.3.21"
 
2122
-        }]
 
2123
-      }
 
2124
-    },
 
2125
-
 
2126
-    "router": {
 
2127
-      "Type": "OS::Quantum::Router"
 
2128
-    },
 
2129
-
 
2130
-    "router_interface": {
 
2131
-      "Type": "OS::Quantum::RouterInterface",
 
2132
-      "Properties": {
 
2133
-        "router_id": { "Ref" : "router" },
 
2134
-        "subnet_id": { "Ref" : "subnet" }
 
2135
-      }
 
2136
-    }
 
2137
-  },
 
2138
-  "Outputs" : {
 
2139
-    "the_network_status" : {
 
2140
-      "Value" : { "Fn::GetAtt" : [ "network", "status" ]},
 
2141
-      "Description" : "Status of network"
 
2142
-    },
 
2143
-    "port_device_owner" : {
 
2144
-      "Value" : { "Fn::GetAtt" : [ "port", "device_owner" ]},
 
2145
-      "Description" : "Device owner of the port"
 
2146
-    },
 
2147
-    "port_fixed_ips" : {
 
2148
-      "Value" : { "Fn::GetAtt" : [ "port", "fixed_ips" ]},
 
2149
-      "Description" : "Fixed IPs of the port"
 
2150
-    },
 
2151
-    "port_mac_address" : {
 
2152
-      "Value" : { "Fn::GetAtt" : [ "port", "mac_address" ]},
 
2153
-      "Description" : "MAC address of the port"
 
2154
-    },
 
2155
-    "port_status" : {
 
2156
-      "Value" : { "Fn::GetAtt" : [ "port", "status" ]},
 
2157
-      "Description" : "Status of the port"
 
2158
-    },
 
2159
-    "port_show" : {
 
2160
-      "Value" : { "Fn::GetAtt" : [ "port", "show" ]},
 
2161
-      "Description" : "All attributes for port"
 
2162
-    },
 
2163
-    "subnet_show" : {
 
2164
-      "Value" : { "Fn::GetAtt" : [ "subnet", "show" ]},
 
2165
-      "Description" : "All attributes for subnet"
 
2166
-    },
 
2167
-    "network_show" : {
 
2168
-      "Value" : { "Fn::GetAtt" : [ "network", "show" ]},
 
2169
-      "Description" : "All attributes for network"
 
2170
-    },
 
2171
-    "router_show" : {
 
2172
-      "Value" : { "Fn::GetAtt" : [ "router", "show" ]},
 
2173
-      "Description" : "All attributes for router"
 
2174
-    }
 
2175
-  }
 
2176
-}
 
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
 
2181
@@ -1,72 +0,0 @@
 
2182
-HeatTemplateFormatVersion: '2012-12-12'
 
2183
-Description: Template to test Quantum resources
 
2184
-Resources:
 
2185
-  network:
 
2186
-    Type: OS::Quantum::Net
 
2187
-    Properties: {name: the_network}
 
2188
-  unnamed_network:
 
2189
-    Type: 'OS::Quantum::Net'
 
2190
-  admin_down_network:
 
2191
-    Type: OS::Quantum::Net
 
2192
-    Properties: {admin_state_up: false}
 
2193
-  subnet:
 
2194
-    Type: OS::Quantum::Subnet
 
2195
-    Properties:
 
2196
-      network_id: {Ref: network}
 
2197
-      ip_version: 4
 
2198
-      cidr: 10.0.3.0/24
 
2199
-      allocation_pools:
 
2200
-      - {end: 10.0.3.150, start: 10.0.3.20}
 
2201
-  port:
 
2202
-    Type: OS::Quantum::Port
 
2203
-    Properties:
 
2204
-      device_id: d6b4d3a5-c700-476f-b609-1493dd9dadc0
 
2205
-      name: port1
 
2206
-      network_id: {Ref: network}
 
2207
-      fixed_ips:
 
2208
-      - subnet_id: {Ref: subnet}
 
2209
-        ip_address: 10.0.3.21
 
2210
-  router:
 
2211
-    Type: 'OS::Quantum::Router'
 
2212
-  router_interface:
 
2213
-    Type: OS::Quantum::RouterInterface
 
2214
-    Properties:
 
2215
-      router_id: {Ref: router}
 
2216
-      subnet_id: {Ref: subnet}
 
2217
-Outputs:
 
2218
-  the_network_status:
 
2219
-    Value:
 
2220
-      Fn::GetAtt: [network, status]
 
2221
-    Description: Status of network
 
2222
-  port_device_owner:
 
2223
-    Value:
 
2224
-      Fn::GetAtt: [port, device_owner]
 
2225
-    Description: Device owner of the port
 
2226
-  port_fixed_ips:
 
2227
-    Value:
 
2228
-      Fn::GetAtt: [port, fixed_ips]
 
2229
-    Description: Fixed IPs of the port
 
2230
-  port_mac_address:
 
2231
-    Value:
 
2232
-      Fn::GetAtt: [port, mac_address]
 
2233
-    Description: MAC address of the port
 
2234
-  port_status:
 
2235
-    Value:
 
2236
-      Fn::GetAtt: [port, status]
 
2237
-    Description: Status of the port
 
2238
-  port_show:
 
2239
-    Value:
 
2240
-      Fn::GetAtt: [port, show]
 
2241
-    Description: All attributes for port
 
2242
-  subnet_show:
 
2243
-    Value:
 
2244
-      Fn::GetAtt: [subnet, show]
 
2245
-    Description: All attributes for subnet
 
2246
-  network_show:
 
2247
-    Value:
 
2248
-      Fn::GetAtt: [network, show]
 
2249
-    Description: All attributes for network
 
2250
-  router_show:
 
2251
-    Value:
 
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 = '''
 
2258
 '''
 
2259
 
 
2260
 
 
2261
-class FakeQuantum(object):
 
2262
+class FakeNeutron(object):
 
2263
 
 
2264
     def show_subnet(self, subnet, **_params):
 
2265
         return {
 
2266
@@ -168,8 +168,8 @@ class instancesTest(HeatTestCase):
 
2267
         self.m.StubOutWithMock(instance, 'nova')
 
2268
         instance.nova().MultipleTimes().AndReturn(self.fc)
 
2269
 
 
2270
-        self.m.StubOutWithMock(instance, 'quantum')
 
2271
-        instance.quantum().MultipleTimes().AndReturn(FakeQuantum())
 
2272
+        self.m.StubOutWithMock(instance, 'neutron')
 
2273
+        instance.neutron().MultipleTimes().AndReturn(FakeNeutron())
 
2274
 
 
2275
         instance.t = instance.stack.resolve_runtime_data(instance.t)
 
2276
 
 
2277
@@ -211,8 +211,8 @@ class instancesTest(HeatTestCase):
 
2278
         instance = instances.Instance('%s_name' % name,
 
2279
                                       t['Resources']['WebServer'], stack)
 
2280
 
 
2281
-        self.m.StubOutWithMock(nic, 'quantum')
 
2282
-        nic.quantum().MultipleTimes().AndReturn(FakeQuantum())
 
2283
+        self.m.StubOutWithMock(nic, 'neutron')
 
2284
+        nic.neutron().MultipleTimes().AndReturn(FakeNeutron())
 
2285
 
 
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
 
2291
@@ -0,0 +1,984 @@
 
2292
+# vim: tabstop=4 shiftwidth=4 softtabstop=4
 
2293
+
 
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
 
2297
+#
 
2298
+#         http://www.apache.org/licenses/LICENSE-2.0
 
2299
+#
 
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.
 
2305
+
 
2306
+
 
2307
+from testtools import skipIf
 
2308
+
 
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
 
2325
+
 
2326
+neutronclient = try_import('neutronclient.v2_0.client')
 
2327
+qe = try_import('neutronclient.common.exceptions')
 
2328
+
 
2329
+neutron_template = '''
 
2330
+{
 
2331
+  "AWSTemplateFormatVersion" : "2010-09-09",
 
2332
+  "Description" : "Template to test Neutron resources",
 
2333
+  "Parameters" : {},
 
2334
+  "Resources" : {
 
2335
+    "network": {
 
2336
+      "Type": "OS::Neutron::Net",
 
2337
+      "Properties": {
 
2338
+        "name": "the_network"
 
2339
+      }
 
2340
+    },
 
2341
+    "unnamed_network": {
 
2342
+      "Type": "OS::Neutron::Net"
 
2343
+    },
 
2344
+    "admin_down_network": {
 
2345
+      "Type": "OS::Neutron::Net",
 
2346
+      "Properties": {
 
2347
+        "admin_state_up": false
 
2348
+      }
 
2349
+    },
 
2350
+    "subnet": {
 
2351
+      "Type": "OS::Neutron::Subnet",
 
2352
+      "Properties": {
 
2353
+        "network_id": { "Ref" : "network" },
 
2354
+        "ip_version": 4,
 
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"]
 
2358
+      }
 
2359
+    },
 
2360
+    "port": {
 
2361
+      "Type": "OS::Neutron::Port",
 
2362
+      "Properties": {
 
2363
+        "device_id": "d6b4d3a5-c700-476f-b609-1493dd9dadc0",
 
2364
+        "name": "port1",
 
2365
+        "network_id": { "Ref" : "network" },
 
2366
+        "fixed_ips": [{
 
2367
+          "subnet_id": { "Ref" : "subnet" },
 
2368
+          "ip_address": "10.0.3.21"
 
2369
+        }]
 
2370
+      }
 
2371
+    },
 
2372
+    "port2": {
 
2373
+      "Type": "OS::Neutron::Port",
 
2374
+      "Properties": {
 
2375
+        "name": "port2",
 
2376
+        "network_id": { "Ref" : "network" }
 
2377
+      }
 
2378
+    },
 
2379
+    "router": {
 
2380
+      "Type": "OS::Neutron::Router"
 
2381
+    },
 
2382
+    "router_interface": {
 
2383
+      "Type": "OS::Neutron::RouterInterface",
 
2384
+      "Properties": {
 
2385
+        "router_id": { "Ref" : "router" },
 
2386
+        "subnet_id": { "Ref" : "subnet" }
 
2387
+      }
 
2388
+    },
 
2389
+    "gateway": {
 
2390
+      "Type": "OS::Neutron::RouterGateway",
 
2391
+      "Properties": {
 
2392
+        "router_id": { "Ref" : "router" },
 
2393
+        "network_id": { "Ref" : "network" }
 
2394
+      }
 
2395
+    }
 
2396
+  }
 
2397
+}
 
2398
+'''
 
2399
+
 
2400
+neutron_floating_template = '''
 
2401
+{
 
2402
+  "AWSTemplateFormatVersion" : "2010-09-09",
 
2403
+  "Description" : "Template to test Neutron resources",
 
2404
+  "Parameters" : {},
 
2405
+  "Resources" : {
 
2406
+    "port_floating": {
 
2407
+      "Type": "OS::Neutron::Port",
 
2408
+      "Properties": {
 
2409
+        "network_id": "xyz1234",
 
2410
+        "fixed_ips": [{
 
2411
+          "subnet_id": "12.12.12.0",
 
2412
+          "ip_address": "10.0.0.10"
 
2413
+        }]
 
2414
+      }
 
2415
+    },
 
2416
+    "floating_ip": {
 
2417
+      "Type": "OS::Neutron::FloatingIP",
 
2418
+      "Properties": {
 
2419
+        "floating_network_id": "abcd1234",
 
2420
+      }
 
2421
+    },
 
2422
+    "floating_ip_assoc": {
 
2423
+      "Type": "OS::Neutron::FloatingIPAssociation",
 
2424
+      "Properties": {
 
2425
+        "floatingip_id": { "Ref" : "floating_ip" },
 
2426
+        "port_id": { "Ref" : "port_floating" }
 
2427
+      }
 
2428
+    },
 
2429
+    "router": {
 
2430
+      "Type": "OS::Neutron::Router"
 
2431
+    },
 
2432
+    "gateway": {
 
2433
+      "Type": "OS::Neutron::RouterGateway",
 
2434
+      "Properties": {
 
2435
+        "router_id": { "Ref" : "router" },
 
2436
+        "network_id": "abcd1234"
 
2437
+      }
 
2438
+    }
 
2439
+  }
 
2440
+}
 
2441
+'''
 
2442
+
 
2443
+
 
2444
+class NeutronTest(HeatTestCase):
 
2445
+
 
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))
 
2452
+
 
2453
+        vs['shared'] = True
 
2454
+        self.assertEqual('shared not allowed in value_specs',
 
2455
+                         qr.validate_properties(p))
 
2456
+        vs.pop('shared')
 
2457
+
 
2458
+        vs['name'] = 'foo'
 
2459
+        self.assertEqual('name not allowed in value_specs',
 
2460
+                         qr.validate_properties(p))
 
2461
+        vs.pop('name')
 
2462
+
 
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')
 
2467
+
 
2468
+        vs['foo'] = '1234'
 
2469
+        self.assertEqual(None, qr.validate_properties(p))
 
2470
+
 
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)
 
2479
+
 
2480
+    def test_is_built(self):
 
2481
+        self.assertTrue(qr.is_built({
 
2482
+            'name': 'the_net',
 
2483
+            'status': 'ACTIVE'
 
2484
+        }))
 
2485
+        self.assertTrue(qr.is_built({
 
2486
+            'name': 'the_net',
 
2487
+            'status': 'DOWN'
 
2488
+        }))
 
2489
+        self.assertFalse(qr.is_built({
 
2490
+            'name': 'the_net',
 
2491
+            'status': 'BUILD'
 
2492
+        }))
 
2493
+        self.assertRaises(exception.Error, qr.is_built, {
 
2494
+            'name': 'the_net',
 
2495
+            'status': 'FROBULATING'
 
2496
+        })
 
2497
+
 
2498
+
 
2499
+@skipIf(neutronclient is None, 'neutronclient unavailable')
 
2500
+class NeutronNetTest(HeatTestCase):
 
2501
+
 
2502
+    def setUp(self):
 
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')
 
2508
+        setup_dummy_db()
 
2509
+
 
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)
 
2514
+        return rsrc
 
2515
+
 
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",
 
2523
+            "subnets": [],
 
2524
+            "name": "name",
 
2525
+            "admin_state_up": False,
 
2526
+            "shared": False,
 
2527
+            "tenant_id": "c1210485b2424d48804aad5d39c61b8f",
 
2528
+            "id": "fc68ea2c-b60b-4b4f-bd82-94ec81110766"
 
2529
+        }})
 
2530
+
 
2531
+        neutronclient.Client.show_network(
 
2532
+            'fc68ea2c-b60b-4b4f-bd82-94ec81110766'
 
2533
+        ).AndReturn({"network": {
 
2534
+            "status": "BUILD",
 
2535
+            "subnets": [],
 
2536
+            "name": "name",
 
2537
+            "admin_state_up": False,
 
2538
+            "shared": False,
 
2539
+            "tenant_id": "c1210485b2424d48804aad5d39c61b8f",
 
2540
+            "id": "fc68ea2c-b60b-4b4f-bd82-94ec81110766"
 
2541
+        }})
 
2542
+
 
2543
+        neutronclient.Client.show_network(
 
2544
+            'fc68ea2c-b60b-4b4f-bd82-94ec81110766'
 
2545
+        ).AndReturn({"network": {
 
2546
+            "status": "ACTIVE",
 
2547
+            "subnets": [],
 
2548
+            "name": "name",
 
2549
+            "admin_state_up": False,
 
2550
+            "shared": False,
 
2551
+            "tenant_id": "c1210485b2424d48804aad5d39c61b8f",
 
2552
+            "id": "fc68ea2c-b60b-4b4f-bd82-94ec81110766"
 
2553
+        }})
 
2554
+
 
2555
+        neutronclient.Client.show_network(
 
2556
+            'fc68ea2c-b60b-4b4f-bd82-94ec81110766'
 
2557
+        ).AndRaise(qe.NeutronClientException(status_code=404))
 
2558
+
 
2559
+        neutronclient.Client.show_network(
 
2560
+            'fc68ea2c-b60b-4b4f-bd82-94ec81110766'
 
2561
+        ).AndReturn({"network": {
 
2562
+            "status": "ACTIVE",
 
2563
+            "subnets": [],
 
2564
+            "name": "name",
 
2565
+            "admin_state_up": False,
 
2566
+            "shared": False,
 
2567
+            "tenant_id": "c1210485b2424d48804aad5d39c61b8f",
 
2568
+            "id": "fc68ea2c-b60b-4b4f-bd82-94ec81110766"
 
2569
+        }})
 
2570
+
 
2571
+        neutronclient.Client.show_network(
 
2572
+            'fc68ea2c-b60b-4b4f-bd82-94ec81110766'
 
2573
+        ).AndReturn({"network": {
 
2574
+            "status": "ACTIVE",
 
2575
+            "subnets": [],
 
2576
+            "name": "name",
 
2577
+            "admin_state_up": False,
 
2578
+            "shared": False,
 
2579
+            "tenant_id": "c1210485b2424d48804aad5d39c61b8f",
 
2580
+            "id": "fc68ea2c-b60b-4b4f-bd82-94ec81110766"
 
2581
+        }})
 
2582
+
 
2583
+        neutronclient.Client.delete_network(
 
2584
+            'fc68ea2c-b60b-4b4f-bd82-94ec81110766'
 
2585
+        ).AndReturn(None)
 
2586
+
 
2587
+        neutronclient.Client.show_network(
 
2588
+            'fc68ea2c-b60b-4b4f-bd82-94ec81110766'
 
2589
+        ).AndRaise(qe.NeutronClientException(status_code=404))
 
2590
+
 
2591
+        neutronclient.Client.delete_network(
 
2592
+            'fc68ea2c-b60b-4b4f-bd82-94ec81110766'
 
2593
+        ).AndRaise(qe.NeutronClientException(status_code=404))
 
2594
+
 
2595
+        self.m.ReplayAll()
 
2596
+        t = template_format.parse(neutron_template)
 
2597
+        stack = parse_stack(t)
 
2598
+        rsrc = self.create_net(t, stack, 'network')
 
2599
+
 
2600
+        # assert the implicit dependency between the gateway and the interface
 
2601
+        deps = stack.dependencies[stack['router_interface']]
 
2602
+        self.assertIn(stack['gateway'], deps)
 
2603
+
 
2604
+        # assert the implicit dependency between the gateway and the subnet
 
2605
+        deps = stack.dependencies[stack['subnet']]
 
2606
+        self.assertIn(stack['gateway'], deps)
 
2607
+
 
2608
+        rsrc.validate()
 
2609
+
 
2610
+        ref_id = rsrc.FnGetRefId()
 
2611
+        self.assertEqual('fc68ea2c-b60b-4b4f-bd82-94ec81110766', ref_id)
 
2612
+
 
2613
+        self.assertEqual(None, rsrc.FnGetAtt('status'))
 
2614
+        self.assertEqual('ACTIVE', rsrc.FnGetAtt('status'))
 
2615
+        try:
 
2616
+            rsrc.FnGetAtt('Foo')
 
2617
+            raise Exception('Expected InvalidTemplateAttribute')
 
2618
+        except exception.InvalidTemplateAttribute:
 
2619
+            pass
 
2620
+
 
2621
+        self.assertEqual('fc68ea2c-b60b-4b4f-bd82-94ec81110766',
 
2622
+                         rsrc.FnGetAtt('id'))
 
2623
+
 
2624
+        self.assertRaises(resource.UpdateReplace,
 
2625
+                          rsrc.handle_update, {}, {}, {})
 
2626
+
 
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()
 
2631
+
 
2632
+
 
2633
+@skipIf(neutronclient is None, 'neutronclient unavailable')
 
2634
+class NeutronSubnetTest(HeatTestCase):
 
2635
+
 
2636
+    def setUp(self):
 
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')
 
2642
+        setup_dummy_db()
 
2643
+
 
2644
+    def create_subnet(self, t, stack, resource_name):
 
2645
+        rsrc = subnet.Subnet('test_subnet', t['Resources'][resource_name],
 
2646
+                             stack)
 
2647
+        scheduler.TaskRunner(rsrc.create)()
 
2648
+        self.assertEqual((rsrc.CREATE, rsrc.COMPLETE), rsrc.state)
 
2649
+        return rsrc
 
2650
+
 
2651
+    def test_subnet(self):
 
2652
+
 
2653
+        clients.OpenStackClients.keystone().AndReturn(
 
2654
+            fakes.FakeKeystoneClient())
 
2655
+        neutronclient.Client.create_subnet({
 
2656
+            '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'}],
 
2662
+                'ip_version': 4,
 
2663
+                'cidr': u'10.0.3.0/24'
 
2664
+            }
 
2665
+        }).AndReturn({
 
2666
+            "subnet": {
 
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",
 
2674
+                "ip_version": 4,
 
2675
+                "name": "name",
 
2676
+                "network_id": "fc68ea2c-b60b-4b4f-bd82-94ec81110766",
 
2677
+                "tenant_id": "c1210485b2424d48804aad5d39c61b8f"
 
2678
+            }
 
2679
+        })
 
2680
+        neutronclient.Client.show_subnet(
 
2681
+            '91e47a57-7508-46fe-afc9-fc454e8580e1').AndRaise(
 
2682
+                qe.NeutronClientException(status_code=404))
 
2683
+        sn = {
 
2684
+            "subnet": {
 
2685
+                "name": "name",
 
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",
 
2691
+                "ip_version": 4,
 
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,
 
2696
+            }
 
2697
+        }
 
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)
 
2704
+
 
2705
+        neutronclient.Client.delete_subnet(
 
2706
+            '91e47a57-7508-46fe-afc9-fc454e8580e1'
 
2707
+        ).AndReturn(None)
 
2708
+
 
2709
+        neutronclient.Client.show_subnet(
 
2710
+            '91e47a57-7508-46fe-afc9-fc454e8580e1'
 
2711
+        ).AndRaise(qe.NeutronClientException(status_code=404))
 
2712
+
 
2713
+        neutronclient.Client.delete_subnet(
 
2714
+            '91e47a57-7508-46fe-afc9-fc454e8580e1'
 
2715
+        ).AndRaise(qe.NeutronClientException(status_code=404))
 
2716
+
 
2717
+        self.m.ReplayAll()
 
2718
+        t = template_format.parse(neutron_template)
 
2719
+        stack = parse_stack(t)
 
2720
+        rsrc = self.create_subnet(t, stack, 'subnet')
 
2721
+
 
2722
+        rsrc.validate()
 
2723
+
 
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'))
 
2733
+
 
2734
+        # assert the dependency (implicit or explicit) between the ports
 
2735
+        # and the subnet
 
2736
+        self.assertIn(stack['port'], stack.dependencies[stack['subnet']])
 
2737
+        self.assertIn(stack['port2'], stack.dependencies[stack['subnet']])
 
2738
+
 
2739
+        self.assertRaises(resource.UpdateReplace,
 
2740
+                          rsrc.handle_update, {}, {}, {})
 
2741
+
 
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()
 
2746
+
 
2747
+    def test_subnet_disable_dhcp(self):
 
2748
+
 
2749
+        clients.OpenStackClients.keystone().AndReturn(
 
2750
+            fakes.FakeKeystoneClient())
 
2751
+        neutronclient.Client.create_subnet({
 
2752
+            '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'}],
 
2758
+                'ip_version': 4,
 
2759
+                'enable_dhcp': False,
 
2760
+                'cidr': u'10.0.3.0/24'
 
2761
+            }
 
2762
+        }).AndReturn({
 
2763
+            "subnet": {
 
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",
 
2771
+                "ip_version": 4,
 
2772
+                "name": "name",
 
2773
+                "network_id": "fc68ea2c-b60b-4b4f-bd82-94ec81110766",
 
2774
+                "tenant_id": "c1210485b2424d48804aad5d39c61b8f"
 
2775
+            }
 
2776
+        })
 
2777
+
 
2778
+        neutronclient.Client.show_subnet(
 
2779
+            '91e47a57-7508-46fe-afc9-fc454e8580e1').AndReturn({
 
2780
+                "subnet": {
 
2781
+                    "name": "name",
 
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",
 
2787
+                    "ip_version": 4,
 
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,
 
2792
+                }
 
2793
+            })
 
2794
+
 
2795
+        neutronclient.Client.delete_subnet(
 
2796
+            '91e47a57-7508-46fe-afc9-fc454e8580e1'
 
2797
+        ).AndReturn(None)
 
2798
+
 
2799
+        neutronclient.Client.show_subnet(
 
2800
+            '91e47a57-7508-46fe-afc9-fc454e8580e1'
 
2801
+        ).AndRaise(qe.NeutronClientException(status_code=404))
 
2802
+
 
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')
 
2808
+
 
2809
+        rsrc.validate()
 
2810
+
 
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()
 
2816
+
 
2817
+
 
2818
+@skipIf(neutronclient is None, 'neutronclient unavailable')
 
2819
+class NeutronRouterTest(HeatTestCase):
 
2820
+    def setUp(self):
 
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')
 
2830
+        setup_dummy_db()
 
2831
+
 
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)
 
2836
+        return rsrc
 
2837
+
 
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],
 
2843
+            stack)
 
2844
+        scheduler.TaskRunner(rsrc.create)()
 
2845
+        self.assertEqual((rsrc.CREATE, rsrc.COMPLETE), rsrc.state)
 
2846
+        return rsrc
 
2847
+
 
2848
+    def create_gateway_router(self, t, stack, resource_name, properties={}):
 
2849
+        t['Resources'][resource_name]['Properties'] = properties
 
2850
+        rsrc = router.RouterGateway(
 
2851
+            'gateway',
 
2852
+            t['Resources'][resource_name],
 
2853
+            stack)
 
2854
+        scheduler.TaskRunner(rsrc.create)()
 
2855
+        self.assertEqual((rsrc.CREATE, rsrc.COMPLETE), rsrc.state)
 
2856
+        return rsrc
 
2857
+
 
2858
+    def test_router(self):
 
2859
+        clients.OpenStackClients.keystone().AndReturn(
 
2860
+            fakes.FakeKeystoneClient())
 
2861
+        neutronclient.Client.create_router({
 
2862
+            'router': {
 
2863
+                'name': utils.PhysName('test_stack', 'router'),
 
2864
+                'admin_state_up': True,
 
2865
+            }
 
2866
+        }).AndReturn({
 
2867
+            "router": {
 
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"
 
2874
+            }
 
2875
+        })
 
2876
+        neutronclient.Client.show_router(
 
2877
+            '3e46229d-8fce-4733-819a-b5fe630550f8').AndReturn({
 
2878
+                "router": {
 
2879
+                    "status": "BUILD",
 
2880
+                    "external_gateway_info": None,
 
2881
+                    "name": utils.PhysName('test_stack', 'router'),
 
2882
+                    "admin_state_up": True,
 
2883
+                    "tenant_id": "3e21026f2dc94372b105808c0e721661",
 
2884
+                    "routes": [],
 
2885
+                    "id": "3e46229d-8fce-4733-819a-b5fe630550f8"
 
2886
+                }
 
2887
+            })
 
2888
+        neutronclient.Client.show_router(
 
2889
+            '3e46229d-8fce-4733-819a-b5fe630550f8').AndReturn({
 
2890
+                "router": {
 
2891
+                    "status": "ACTIVE",
 
2892
+                    "external_gateway_info": None,
 
2893
+                    "name": utils.PhysName('test_stack', 'router'),
 
2894
+                    "admin_state_up": True,
 
2895
+                    "tenant_id": "3e21026f2dc94372b105808c0e721661",
 
2896
+                    "routes": [],
 
2897
+                    "id": "3e46229d-8fce-4733-819a-b5fe630550f8"
 
2898
+                }
 
2899
+            })
 
2900
+
 
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({
 
2906
+                "router": {
 
2907
+                    "status": "ACTIVE",
 
2908
+                    "external_gateway_info": None,
 
2909
+                    "name": utils.PhysName('test_stack', 'router'),
 
2910
+                    "admin_state_up": True,
 
2911
+                    "tenant_id": "3e21026f2dc94372b105808c0e721661",
 
2912
+                    "routes": [],
 
2913
+                    "id": "3e46229d-8fce-4733-819a-b5fe630550f8"
 
2914
+                }
 
2915
+            })
 
2916
+        neutronclient.Client.show_router(
 
2917
+            '3e46229d-8fce-4733-819a-b5fe630550f8').AndReturn({
 
2918
+                "router": {
 
2919
+                    "status": "ACTIVE",
 
2920
+                    "external_gateway_info": None,
 
2921
+                    "name": utils.PhysName('test_stack', 'router'),
 
2922
+                    "admin_state_up": True,
 
2923
+                    "tenant_id": "3e21026f2dc94372b105808c0e721661",
 
2924
+                    "routes": [],
 
2925
+                    "id": "3e46229d-8fce-4733-819a-b5fe630550f8"
 
2926
+                }
 
2927
+            })
 
2928
+
 
2929
+        neutronclient.Client.delete_router(
 
2930
+            '3e46229d-8fce-4733-819a-b5fe630550f8'
 
2931
+        ).AndReturn(None)
 
2932
+
 
2933
+        neutronclient.Client.show_router(
 
2934
+            '3e46229d-8fce-4733-819a-b5fe630550f8'
 
2935
+        ).AndRaise(qe.NeutronClientException(status_code=404))
 
2936
+
 
2937
+        neutronclient.Client.delete_router(
 
2938
+            '3e46229d-8fce-4733-819a-b5fe630550f8'
 
2939
+        ).AndRaise(qe.NeutronClientException(status_code=404))
 
2940
+
 
2941
+        self.m.ReplayAll()
 
2942
+        t = template_format.parse(neutron_template)
 
2943
+        stack = parse_stack(t)
 
2944
+        rsrc = self.create_router(t, stack, 'router')
 
2945
+
 
2946
+        rsrc.validate()
 
2947
+
 
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'))
 
2956
+
 
2957
+        self.assertRaises(resource.UpdateReplace,
 
2958
+                          rsrc.handle_update, {}, {}, {})
 
2959
+
 
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()
 
2964
+
 
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'}
 
2971
+        ).AndReturn(None)
 
2972
+        neutronclient.Client.remove_interface_router(
 
2973
+            '3e46229d-8fce-4733-819a-b5fe630550f8',
 
2974
+            {'subnet_id': '91e47a57-7508-46fe-afc9-fc454e8580e1'}
 
2975
+        ).AndReturn(None)
 
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)
 
2983
+
 
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'
 
2988
+            })
 
2989
+
 
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()
 
2994
+
 
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'}
 
3001
+        ).AndReturn(None)
 
3002
+        neutronclient.Client.remove_gateway_router(
 
3003
+            '3e46229d-8fce-4733-819a-b5fe630550f8'
 
3004
+        ).AndReturn(None)
 
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)
 
3011
+
 
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'
 
3016
+            })
 
3017
+
 
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()
 
3022
+
 
3023
+
 
3024
+@skipIf(neutronclient is None, 'neutronclient unavailable')
 
3025
+class NeutronFloatingIPTest(HeatTestCase):
 
3026
+    @skipIf(net.clients.neutronclient is None, "Missing Neutron Client")
 
3027
+    def setUp(self):
 
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')
 
3037
+        setup_dummy_db()
 
3038
+
 
3039
+    def test_floating_ip(self):
 
3040
+
 
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"
 
3048
+        }})
 
3049
+
 
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"
 
3058
+        }})
 
3059
+
 
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()
 
3066
+
 
3067
+        t = template_format.parse(neutron_floating_template)
 
3068
+        stack = parse_stack(t)
 
3069
+
 
3070
+        # assert the implicit dependency between the floating_ip
 
3071
+        # and the gateway
 
3072
+        deps = stack.dependencies[stack['gateway']]
 
3073
+        self.assertIn(stack['floating_ip'], deps)
 
3074
+
 
3075
+        fip = stack['floating_ip']
 
3076
+        scheduler.TaskRunner(fip.create)()
 
3077
+        self.assertEqual((fip.CREATE, fip.COMPLETE), fip.state)
 
3078
+        fip.validate()
 
3079
+
 
3080
+        fip_id = fip.FnGetRefId()
 
3081
+        self.assertEqual('fc68ea2c-b60b-4b4f-bd82-94ec81110766', fip_id)
 
3082
+
 
3083
+        self.assertEqual(None, fip.FnGetAtt('status'))
 
3084
+        self.assertEqual('ACTIVE', fip.FnGetAtt('status'))
 
3085
+        try:
 
3086
+            fip.FnGetAtt('Foo')
 
3087
+            raise Exception('Expected InvalidTemplateAttribute')
 
3088
+        except exception.InvalidTemplateAttribute:
 
3089
+            pass
 
3090
+
 
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)
 
3098
+
 
3099
+        self.m.VerifyAll()
 
3100
+
 
3101
+    def test_port(self):
 
3102
+
 
3103
+        clients.OpenStackClients.keystone().AndReturn(
 
3104
+            fakes.FakeKeystoneClient())
 
3105
+        neutronclient.Client.create_port({'port': {
 
3106
+            'network_id': u'xyz1234',
 
3107
+            'fixed_ips': [
 
3108
+                {'subnet_id': u'12.12.12.0', 'ip_address': u'10.0.0.10'}
 
3109
+            ],
 
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"
 
3115
+        }})
 
3116
+        neutronclient.Client.show_port(
 
3117
+            'fc68ea2c-b60b-4b4f-bd82-94ec81110766'
 
3118
+        ).AndReturn({'port': {
 
3119
+            "status": "BUILD",
 
3120
+            "id": "fc68ea2c-b60b-4b4f-bd82-94ec81110766"
 
3121
+        }})
 
3122
+        neutronclient.Client.show_port(
 
3123
+            'fc68ea2c-b60b-4b4f-bd82-94ec81110766'
 
3124
+        ).AndReturn({'port': {
 
3125
+            "status": "ACTIVE",
 
3126
+            "id": "fc68ea2c-b60b-4b4f-bd82-94ec81110766"
 
3127
+        }})
 
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"
 
3136
+        }})
 
3137
+
 
3138
+        self.m.ReplayAll()
 
3139
+
 
3140
+        t = template_format.parse(neutron_floating_template)
 
3141
+        stack = parse_stack(t)
 
3142
+
 
3143
+        p = stack['port_floating']
 
3144
+        scheduler.TaskRunner(p.create)()
 
3145
+        self.assertEqual((p.CREATE, p.COMPLETE), p.state)
 
3146
+        p.validate()
 
3147
+
 
3148
+        port_id = p.FnGetRefId()
 
3149
+        self.assertEqual('fc68ea2c-b60b-4b4f-bd82-94ec81110766', port_id)
 
3150
+
 
3151
+        self.assertEqual(None, p.FnGetAtt('status'))
 
3152
+        self.assertEqual('ACTIVE', p.FnGetAtt('status'))
 
3153
+        try:
 
3154
+            p.FnGetAtt('Foo')
 
3155
+            raise Exception('Expected InvalidTemplateAttribute')
 
3156
+        except exception.InvalidTemplateAttribute:
 
3157
+            pass
 
3158
+
 
3159
+        self.assertEqual('fc68ea2c-b60b-4b4f-bd82-94ec81110766',
 
3160
+                         p.FnGetAtt('id'))
 
3161
+
 
3162
+        self.assertRaises(resource.UpdateReplace,
 
3163
+                          p.handle_update, {}, {}, {})
 
3164
+
 
3165
+        self.m.VerifyAll()
 
3166
+
 
3167
+    def test_floatip_port(self):
 
3168
+
 
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"
 
3176
+        }})
 
3177
+
 
3178
+        neutronclient.Client.create_port({'port': {
 
3179
+            'network_id': u'xyz1234',
 
3180
+            'fixed_ips': [
 
3181
+                {'subnet_id': u'12.12.12.0', 'ip_address': u'10.0.0.10'}
 
3182
+            ],
 
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"
 
3188
+        }})
 
3189
+        neutronclient.Client.show_port(
 
3190
+            'fc68ea2c-b60b-4b4f-bd82-94ec81110766'
 
3191
+        ).AndReturn({'port': {
 
3192
+            "status": "ACTIVE",
 
3193
+            "id": "fc68ea2c-b60b-4b4f-bd82-94ec81110766"
 
3194
+        }})
 
3195
+        neutronclient.Client.update_floatingip(
 
3196
+            'fc68ea2c-b60b-4b4f-bd82-94ec81110766',
 
3197
+            {
 
3198
+                'floatingip': {
 
3199
+                    'port_id': u'fc68ea2c-b60b-4b4f-bd82-94ec81110766'}}
 
3200
+        ).AndReturn({'floatingip': {
 
3201
+            "status": "ACTIVE",
 
3202
+            "id": "fc68ea2c-b60b-4b4f-bd82-94ec81110766"
 
3203
+        }})
 
3204
+
 
3205
+        neutronclient.Client.update_floatingip(
 
3206
+            'fc68ea2c-b60b-4b4f-bd82-94ec81110766',
 
3207
+            {'floatingip': {
 
3208
+                'port_id': None
 
3209
+            }}).AndReturn(None)
 
3210
+
 
3211
+        neutronclient.Client.delete_port(
 
3212
+            'fc68ea2c-b60b-4b4f-bd82-94ec81110766'
 
3213
+        ).AndReturn(None)
 
3214
+
 
3215
+        neutronclient.Client.show_port(
 
3216
+            'fc68ea2c-b60b-4b4f-bd82-94ec81110766'
 
3217
+        ).AndRaise(qe.NeutronClientException(status_code=404))
 
3218
+
 
3219
+        neutronclient.Client.delete_floatingip(
 
3220
+            'fc68ea2c-b60b-4b4f-bd82-94ec81110766'
 
3221
+        ).AndReturn(None)
 
3222
+
 
3223
+        neutronclient.Client.update_floatingip(
 
3224
+            'fc68ea2c-b60b-4b4f-bd82-94ec81110766',
 
3225
+            {'floatingip': {
 
3226
+                'port_id': None
 
3227
+            }}).AndRaise(qe.NeutronClientException(status_code=404))
 
3228
+
 
3229
+        neutronclient.Client.delete_port(
 
3230
+            'fc68ea2c-b60b-4b4f-bd82-94ec81110766'
 
3231
+        ).AndRaise(qe.NeutronClientException(status_code=404))
 
3232
+
 
3233
+        neutronclient.Client.delete_floatingip(
 
3234
+            'fc68ea2c-b60b-4b4f-bd82-94ec81110766'
 
3235
+        ).AndRaise(qe.NeutronClientException(status_code=404))
 
3236
+
 
3237
+        self.m.ReplayAll()
 
3238
+
 
3239
+        t = template_format.parse(neutron_floating_template)
 
3240
+        stack = parse_stack(t)
 
3241
+
 
3242
+        fip = stack['floating_ip']
 
3243
+        scheduler.TaskRunner(fip.create)()
 
3244
+        self.assertEqual((fip.CREATE, fip.COMPLETE), fip.state)
 
3245
+
 
3246
+        p = stack['port_floating']
 
3247
+        scheduler.TaskRunner(p.create)()
 
3248
+        self.assertEqual((p.CREATE, p.COMPLETE), p.state)
 
3249
+
 
3250
+        fipa = stack['floating_ip_assoc']
 
3251
+        scheduler.TaskRunner(fipa.create)()
 
3252
+        self.assertEqual((fipa.CREATE, fipa.COMPLETE), fipa.state)
 
3253
+
 
3254
+        fipa.validate()
 
3255
+
 
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, {}, {}, {})
 
3262
+
 
3263
+        self.assertEqual(fipa.delete(), None)
 
3264
+        self.assertEqual(scheduler.TaskRunner(p.delete)(), None)
 
3265
+        self.assertEqual(fip.delete(), None)
 
3266
+
 
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')
 
3270
+
 
3271
+        self.assertEqual(fipa.delete(), None)
 
3272
+        self.assertEqual(scheduler.TaskRunner(p.delete)(), None)
 
3273
+        self.assertEqual(fip.delete(), None)
 
3274
+
 
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
 
3279
@@ -1,960 +0,0 @@
 
3280
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
 
3281
-
 
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
 
3285
-#
 
3286
-#         http://www.apache.org/licenses/LICENSE-2.0
 
3287
-#
 
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.
 
3293
-
 
3294
-
 
3295
-from testtools import skipIf
 
3296
-
 
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
 
3311
-
 
3312
-quantumclient = try_import('quantumclient.v2_0.client')
 
3313
-qe = try_import('quantumclient.common.exceptions')
 
3314
-
 
3315
-quantum_template = '''
 
3316
-{
 
3317
-  "AWSTemplateFormatVersion" : "2010-09-09",
 
3318
-  "Description" : "Template to test Quantum resources",
 
3319
-  "Parameters" : {},
 
3320
-  "Resources" : {
 
3321
-    "network": {
 
3322
-      "Type": "OS::Quantum::Net",
 
3323
-      "Properties": {
 
3324
-        "name": "the_network"
 
3325
-      }
 
3326
-    },
 
3327
-    "unnamed_network": {
 
3328
-      "Type": "OS::Quantum::Net"
 
3329
-    },
 
3330
-    "admin_down_network": {
 
3331
-      "Type": "OS::Quantum::Net",
 
3332
-      "Properties": {
 
3333
-        "admin_state_up": false
 
3334
-      }
 
3335
-    },
 
3336
-    "subnet": {
 
3337
-      "Type": "OS::Quantum::Subnet",
 
3338
-      "Properties": {
 
3339
-        "network_id": { "Ref" : "network" },
 
3340
-        "ip_version": 4,
 
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"]
 
3344
-      }
 
3345
-    },
 
3346
-    "port": {
 
3347
-      "Type": "OS::Quantum::Port",
 
3348
-      "Properties": {
 
3349
-        "device_id": "d6b4d3a5-c700-476f-b609-1493dd9dadc0",
 
3350
-        "name": "port1",
 
3351
-        "network_id": { "Ref" : "network" },
 
3352
-        "fixed_ips": [{
 
3353
-          "subnet_id": { "Ref" : "subnet" },
 
3354
-          "ip_address": "10.0.3.21"
 
3355
-        }]
 
3356
-      }
 
3357
-    },
 
3358
-    "port2": {
 
3359
-      "Type": "OS::Quantum::Port",
 
3360
-      "Properties": {
 
3361
-        "name": "port2",
 
3362
-        "network_id": { "Ref" : "network" }
 
3363
-      }
 
3364
-    },
 
3365
-    "router": {
 
3366
-      "Type": "OS::Quantum::Router"
 
3367
-    },
 
3368
-    "router_interface": {
 
3369
-      "Type": "OS::Quantum::RouterInterface",
 
3370
-      "Properties": {
 
3371
-        "router_id": { "Ref" : "router" },
 
3372
-        "subnet_id": { "Ref" : "subnet" }
 
3373
-      }
 
3374
-    },
 
3375
-    "gateway": {
 
3376
-      "Type": "OS::Quantum::RouterGateway",
 
3377
-      "Properties": {
 
3378
-        "router_id": { "Ref" : "router" },
 
3379
-        "network_id": { "Ref" : "network" }
 
3380
-      }
 
3381
-    }
 
3382
-  }
 
3383
-}
 
3384
-'''
 
3385
-
 
3386
-quantum_floating_template = '''
 
3387
-{
 
3388
-  "AWSTemplateFormatVersion" : "2010-09-09",
 
3389
-  "Description" : "Template to test Quantum resources",
 
3390
-  "Parameters" : {},
 
3391
-  "Resources" : {
 
3392
-    "port_floating": {
 
3393
-      "Type": "OS::Quantum::Port",
 
3394
-      "Properties": {
 
3395
-        "network_id": "xyz1234",
 
3396
-        "fixed_ips": [{
 
3397
-          "subnet_id": "12.12.12.0",
 
3398
-          "ip_address": "10.0.0.10"
 
3399
-        }]
 
3400
-      }
 
3401
-    },
 
3402
-    "floating_ip": {
 
3403
-      "Type": "OS::Quantum::FloatingIP",
 
3404
-      "Properties": {
 
3405
-        "floating_network_id": "abcd1234",
 
3406
-      }
 
3407
-    },
 
3408
-    "floating_ip_assoc": {
 
3409
-      "Type": "OS::Quantum::FloatingIPAssociation",
 
3410
-      "Properties": {
 
3411
-        "floatingip_id": { "Ref" : "floating_ip" },
 
3412
-        "port_id": { "Ref" : "port_floating" }
 
3413
-      }
 
3414
-    },
 
3415
-    "router": {
 
3416
-      "Type": "OS::Quantum::Router"
 
3417
-    },
 
3418
-    "gateway": {
 
3419
-      "Type": "OS::Quantum::RouterGateway",
 
3420
-      "Properties": {
 
3421
-        "router_id": { "Ref" : "router" },
 
3422
-        "network_id": "abcd1234"
 
3423
-      }
 
3424
-    }
 
3425
-  }
 
3426
-}
 
3427
-'''
 
3428
-
 
3429
-
 
3430
-class QuantumTest(HeatTestCase):
 
3431
-
 
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))
 
3438
-
 
3439
-        vs['shared'] = True
 
3440
-        self.assertEqual('shared not allowed in value_specs',
 
3441
-                         qr.validate_properties(p))
 
3442
-        vs.pop('shared')
 
3443
-
 
3444
-        vs['name'] = 'foo'
 
3445
-        self.assertEqual('name not allowed in value_specs',
 
3446
-                         qr.validate_properties(p))
 
3447
-        vs.pop('name')
 
3448
-
 
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')
 
3453
-
 
3454
-        vs['foo'] = '1234'
 
3455
-        self.assertEqual(None, qr.validate_properties(p))
 
3456
-
 
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)
 
3465
-
 
3466
-    def test_is_built(self):
 
3467
-        self.assertTrue(qr.is_built({
 
3468
-            'name': 'the_net',
 
3469
-            'status': 'ACTIVE'
 
3470
-        }))
 
3471
-        self.assertTrue(qr.is_built({
 
3472
-            'name': 'the_net',
 
3473
-            'status': 'DOWN'
 
3474
-        }))
 
3475
-        self.assertFalse(qr.is_built({
 
3476
-            'name': 'the_net',
 
3477
-            'status': 'BUILD'
 
3478
-        }))
 
3479
-        self.assertRaises(exception.Error, qr.is_built, {
 
3480
-            'name': 'the_net',
 
3481
-            'status': 'FROBULATING'
 
3482
-        })
 
3483
-
 
3484
-
 
3485
-@skipIf(quantumclient is None, 'quantumclient unavailable')
 
3486
-class QuantumNetTest(HeatTestCase):
 
3487
-
 
3488
-    def setUp(self):
 
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')
 
3493
-        setup_dummy_db()
 
3494
-
 
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)
 
3499
-        return rsrc
 
3500
-
 
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",
 
3506
-            "subnets": [],
 
3507
-            "name": "name",
 
3508
-            "admin_state_up": False,
 
3509
-            "shared": False,
 
3510
-            "tenant_id": "c1210485b2424d48804aad5d39c61b8f",
 
3511
-            "id": "fc68ea2c-b60b-4b4f-bd82-94ec81110766"
 
3512
-        }})
 
3513
-
 
3514
-        quantumclient.Client.show_network(
 
3515
-            'fc68ea2c-b60b-4b4f-bd82-94ec81110766'
 
3516
-        ).AndReturn({"network": {
 
3517
-            "status": "BUILD",
 
3518
-            "subnets": [],
 
3519
-            "name": "name",
 
3520
-            "admin_state_up": False,
 
3521
-            "shared": False,
 
3522
-            "tenant_id": "c1210485b2424d48804aad5d39c61b8f",
 
3523
-            "id": "fc68ea2c-b60b-4b4f-bd82-94ec81110766"
 
3524
-        }})
 
3525
-
 
3526
-        quantumclient.Client.show_network(
 
3527
-            'fc68ea2c-b60b-4b4f-bd82-94ec81110766'
 
3528
-        ).AndReturn({"network": {
 
3529
-            "status": "ACTIVE",
 
3530
-            "subnets": [],
 
3531
-            "name": "name",
 
3532
-            "admin_state_up": False,
 
3533
-            "shared": False,
 
3534
-            "tenant_id": "c1210485b2424d48804aad5d39c61b8f",
 
3535
-            "id": "fc68ea2c-b60b-4b4f-bd82-94ec81110766"
 
3536
-        }})
 
3537
-
 
3538
-        quantumclient.Client.show_network(
 
3539
-            'fc68ea2c-b60b-4b4f-bd82-94ec81110766'
 
3540
-        ).AndRaise(qe.QuantumClientException(status_code=404))
 
3541
-
 
3542
-        quantumclient.Client.show_network(
 
3543
-            'fc68ea2c-b60b-4b4f-bd82-94ec81110766'
 
3544
-        ).AndReturn({"network": {
 
3545
-            "status": "ACTIVE",
 
3546
-            "subnets": [],
 
3547
-            "name": "name",
 
3548
-            "admin_state_up": False,
 
3549
-            "shared": False,
 
3550
-            "tenant_id": "c1210485b2424d48804aad5d39c61b8f",
 
3551
-            "id": "fc68ea2c-b60b-4b4f-bd82-94ec81110766"
 
3552
-        }})
 
3553
-
 
3554
-        quantumclient.Client.show_network(
 
3555
-            'fc68ea2c-b60b-4b4f-bd82-94ec81110766'
 
3556
-        ).AndReturn({"network": {
 
3557
-            "status": "ACTIVE",
 
3558
-            "subnets": [],
 
3559
-            "name": "name",
 
3560
-            "admin_state_up": False,
 
3561
-            "shared": False,
 
3562
-            "tenant_id": "c1210485b2424d48804aad5d39c61b8f",
 
3563
-            "id": "fc68ea2c-b60b-4b4f-bd82-94ec81110766"
 
3564
-        }})
 
3565
-
 
3566
-        quantumclient.Client.delete_network(
 
3567
-            'fc68ea2c-b60b-4b4f-bd82-94ec81110766'
 
3568
-        ).AndReturn(None)
 
3569
-
 
3570
-        quantumclient.Client.show_network(
 
3571
-            'fc68ea2c-b60b-4b4f-bd82-94ec81110766'
 
3572
-        ).AndRaise(qe.QuantumClientException(status_code=404))
 
3573
-
 
3574
-        quantumclient.Client.delete_network(
 
3575
-            'fc68ea2c-b60b-4b4f-bd82-94ec81110766'
 
3576
-        ).AndRaise(qe.QuantumClientException(status_code=404))
 
3577
-
 
3578
-        self.m.ReplayAll()
 
3579
-        t = template_format.parse(quantum_template)
 
3580
-        stack = parse_stack(t)
 
3581
-        rsrc = self.create_net(t, stack, 'network')
 
3582
-
 
3583
-        # assert the implicit dependency between the gateway and the interface
 
3584
-        deps = stack.dependencies[stack['router_interface']]
 
3585
-        self.assertIn(stack['gateway'], deps)
 
3586
-
 
3587
-        # assert the implicit dependency between the gateway and the subnet
 
3588
-        deps = stack.dependencies[stack['subnet']]
 
3589
-        self.assertIn(stack['gateway'], deps)
 
3590
-
 
3591
-        rsrc.validate()
 
3592
-
 
3593
-        ref_id = rsrc.FnGetRefId()
 
3594
-        self.assertEqual('fc68ea2c-b60b-4b4f-bd82-94ec81110766', ref_id)
 
3595
-
 
3596
-        self.assertEqual(None, rsrc.FnGetAtt('status'))
 
3597
-        self.assertEqual('ACTIVE', rsrc.FnGetAtt('status'))
 
3598
-        try:
 
3599
-            rsrc.FnGetAtt('Foo')
 
3600
-            raise Exception('Expected InvalidTemplateAttribute')
 
3601
-        except exception.InvalidTemplateAttribute:
 
3602
-            pass
 
3603
-
 
3604
-        self.assertEqual('fc68ea2c-b60b-4b4f-bd82-94ec81110766',
 
3605
-                         rsrc.FnGetAtt('id'))
 
3606
-
 
3607
-        self.assertRaises(resource.UpdateReplace,
 
3608
-                          rsrc.handle_update, {}, {}, {})
 
3609
-
 
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()
 
3614
-
 
3615
-
 
3616
-@skipIf(quantumclient is None, 'quantumclient unavailable')
 
3617
-class QuantumSubnetTest(HeatTestCase):
 
3618
-
 
3619
-    def setUp(self):
 
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')
 
3624
-        setup_dummy_db()
 
3625
-
 
3626
-    def create_subnet(self, t, stack, resource_name):
 
3627
-        rsrc = subnet.Subnet('test_subnet', t['Resources'][resource_name],
 
3628
-                             stack)
 
3629
-        scheduler.TaskRunner(rsrc.create)()
 
3630
-        self.assertEqual((rsrc.CREATE, rsrc.COMPLETE), rsrc.state)
 
3631
-        return rsrc
 
3632
-
 
3633
-    def test_subnet(self):
 
3634
-
 
3635
-        quantumclient.Client.create_subnet({
 
3636
-            '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'}],
 
3642
-                'ip_version': 4,
 
3643
-                'cidr': u'10.0.3.0/24'
 
3644
-            }
 
3645
-        }).AndReturn({
 
3646
-            "subnet": {
 
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",
 
3654
-                "ip_version": 4,
 
3655
-                "name": "name",
 
3656
-                "network_id": "fc68ea2c-b60b-4b4f-bd82-94ec81110766",
 
3657
-                "tenant_id": "c1210485b2424d48804aad5d39c61b8f"
 
3658
-            }
 
3659
-        })
 
3660
-        quantumclient.Client.show_subnet(
 
3661
-            '91e47a57-7508-46fe-afc9-fc454e8580e1').AndRaise(
 
3662
-                qe.QuantumClientException(status_code=404))
 
3663
-        sn = {
 
3664
-            "subnet": {
 
3665
-                "name": "name",
 
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",
 
3671
-                "ip_version": 4,
 
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,
 
3676
-            }
 
3677
-        }
 
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)
 
3684
-
 
3685
-        quantumclient.Client.delete_subnet(
 
3686
-            '91e47a57-7508-46fe-afc9-fc454e8580e1'
 
3687
-        ).AndReturn(None)
 
3688
-
 
3689
-        quantumclient.Client.show_subnet(
 
3690
-            '91e47a57-7508-46fe-afc9-fc454e8580e1'
 
3691
-        ).AndRaise(qe.QuantumClientException(status_code=404))
 
3692
-
 
3693
-        quantumclient.Client.delete_subnet(
 
3694
-            '91e47a57-7508-46fe-afc9-fc454e8580e1'
 
3695
-        ).AndRaise(qe.QuantumClientException(status_code=404))
 
3696
-
 
3697
-        self.m.ReplayAll()
 
3698
-        t = template_format.parse(quantum_template)
 
3699
-        stack = parse_stack(t)
 
3700
-        rsrc = self.create_subnet(t, stack, 'subnet')
 
3701
-
 
3702
-        rsrc.validate()
 
3703
-
 
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'))
 
3713
-
 
3714
-        # assert the dependency (implicit or explicit) between the ports
 
3715
-        # and the subnet
 
3716
-        self.assertIn(stack['port'], stack.dependencies[stack['subnet']])
 
3717
-        self.assertIn(stack['port2'], stack.dependencies[stack['subnet']])
 
3718
-
 
3719
-        self.assertRaises(resource.UpdateReplace,
 
3720
-                          rsrc.handle_update, {}, {}, {})
 
3721
-
 
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()
 
3726
-
 
3727
-    def test_subnet_disable_dhcp(self):
 
3728
-
 
3729
-        quantumclient.Client.create_subnet({
 
3730
-            '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'}],
 
3736
-                'ip_version': 4,
 
3737
-                'enable_dhcp': False,
 
3738
-                'cidr': u'10.0.3.0/24'
 
3739
-            }
 
3740
-        }).AndReturn({
 
3741
-            "subnet": {
 
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",
 
3749
-                "ip_version": 4,
 
3750
-                "name": "name",
 
3751
-                "network_id": "fc68ea2c-b60b-4b4f-bd82-94ec81110766",
 
3752
-                "tenant_id": "c1210485b2424d48804aad5d39c61b8f"
 
3753
-            }
 
3754
-        })
 
3755
-
 
3756
-        quantumclient.Client.show_subnet(
 
3757
-            '91e47a57-7508-46fe-afc9-fc454e8580e1').AndReturn({
 
3758
-                "subnet": {
 
3759
-                    "name": "name",
 
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",
 
3765
-                    "ip_version": 4,
 
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,
 
3770
-                }
 
3771
-            })
 
3772
-
 
3773
-        quantumclient.Client.delete_subnet(
 
3774
-            '91e47a57-7508-46fe-afc9-fc454e8580e1'
 
3775
-        ).AndReturn(None)
 
3776
-
 
3777
-        quantumclient.Client.show_subnet(
 
3778
-            '91e47a57-7508-46fe-afc9-fc454e8580e1'
 
3779
-        ).AndRaise(qe.QuantumClientException(status_code=404))
 
3780
-
 
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')
 
3786
-
 
3787
-        rsrc.validate()
 
3788
-
 
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()
 
3794
-
 
3795
-
 
3796
-@skipIf(quantumclient is None, 'quantumclient unavailable')
 
3797
-class QuantumRouterTest(HeatTestCase):
 
3798
-    def setUp(self):
 
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')
 
3807
-        setup_dummy_db()
 
3808
-
 
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)
 
3813
-        return rsrc
 
3814
-
 
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],
 
3820
-            stack)
 
3821
-        scheduler.TaskRunner(rsrc.create)()
 
3822
-        self.assertEqual((rsrc.CREATE, rsrc.COMPLETE), rsrc.state)
 
3823
-        return rsrc
 
3824
-
 
3825
-    def create_gateway_router(self, t, stack, resource_name, properties={}):
 
3826
-        t['Resources'][resource_name]['Properties'] = properties
 
3827
-        rsrc = router.RouterGateway(
 
3828
-            'gateway',
 
3829
-            t['Resources'][resource_name],
 
3830
-            stack)
 
3831
-        scheduler.TaskRunner(rsrc.create)()
 
3832
-        self.assertEqual((rsrc.CREATE, rsrc.COMPLETE), rsrc.state)
 
3833
-        return rsrc
 
3834
-
 
3835
-    def test_router(self):
 
3836
-        quantumclient.Client.create_router({
 
3837
-            'router': {
 
3838
-                'name': utils.PhysName('test_stack', 'router'),
 
3839
-                'admin_state_up': True,
 
3840
-            }
 
3841
-        }).AndReturn({
 
3842
-            "router": {
 
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"
 
3849
-            }
 
3850
-        })
 
3851
-        quantumclient.Client.show_router(
 
3852
-            '3e46229d-8fce-4733-819a-b5fe630550f8').AndReturn({
 
3853
-                "router": {
 
3854
-                    "status": "BUILD",
 
3855
-                    "external_gateway_info": None,
 
3856
-                    "name": utils.PhysName('test_stack', 'router'),
 
3857
-                    "admin_state_up": True,
 
3858
-                    "tenant_id": "3e21026f2dc94372b105808c0e721661",
 
3859
-                    "routes": [],
 
3860
-                    "id": "3e46229d-8fce-4733-819a-b5fe630550f8"
 
3861
-                }
 
3862
-            })
 
3863
-        quantumclient.Client.show_router(
 
3864
-            '3e46229d-8fce-4733-819a-b5fe630550f8').AndReturn({
 
3865
-                "router": {
 
3866
-                    "status": "ACTIVE",
 
3867
-                    "external_gateway_info": None,
 
3868
-                    "name": utils.PhysName('test_stack', 'router'),
 
3869
-                    "admin_state_up": True,
 
3870
-                    "tenant_id": "3e21026f2dc94372b105808c0e721661",
 
3871
-                    "routes": [],
 
3872
-                    "id": "3e46229d-8fce-4733-819a-b5fe630550f8"
 
3873
-                }
 
3874
-            })
 
3875
-
 
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({
 
3881
-                "router": {
 
3882
-                    "status": "ACTIVE",
 
3883
-                    "external_gateway_info": None,
 
3884
-                    "name": utils.PhysName('test_stack', 'router'),
 
3885
-                    "admin_state_up": True,
 
3886
-                    "tenant_id": "3e21026f2dc94372b105808c0e721661",
 
3887
-                    "routes": [],
 
3888
-                    "id": "3e46229d-8fce-4733-819a-b5fe630550f8"
 
3889
-                }
 
3890
-            })
 
3891
-        quantumclient.Client.show_router(
 
3892
-            '3e46229d-8fce-4733-819a-b5fe630550f8').AndReturn({
 
3893
-                "router": {
 
3894
-                    "status": "ACTIVE",
 
3895
-                    "external_gateway_info": None,
 
3896
-                    "name": utils.PhysName('test_stack', 'router'),
 
3897
-                    "admin_state_up": True,
 
3898
-                    "tenant_id": "3e21026f2dc94372b105808c0e721661",
 
3899
-                    "routes": [],
 
3900
-                    "id": "3e46229d-8fce-4733-819a-b5fe630550f8"
 
3901
-                }
 
3902
-            })
 
3903
-
 
3904
-        quantumclient.Client.delete_router(
 
3905
-            '3e46229d-8fce-4733-819a-b5fe630550f8'
 
3906
-        ).AndReturn(None)
 
3907
-
 
3908
-        quantumclient.Client.show_router(
 
3909
-            '3e46229d-8fce-4733-819a-b5fe630550f8'
 
3910
-        ).AndRaise(qe.QuantumClientException(status_code=404))
 
3911
-
 
3912
-        quantumclient.Client.delete_router(
 
3913
-            '3e46229d-8fce-4733-819a-b5fe630550f8'
 
3914
-        ).AndRaise(qe.QuantumClientException(status_code=404))
 
3915
-
 
3916
-        self.m.ReplayAll()
 
3917
-        t = template_format.parse(quantum_template)
 
3918
-        stack = parse_stack(t)
 
3919
-        rsrc = self.create_router(t, stack, 'router')
 
3920
-
 
3921
-        rsrc.validate()
 
3922
-
 
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'))
 
3931
-
 
3932
-        self.assertRaises(resource.UpdateReplace,
 
3933
-                          rsrc.handle_update, {}, {}, {})
 
3934
-
 
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()
 
3939
-
 
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'}
 
3944
-        ).AndReturn(None)
 
3945
-        quantumclient.Client.remove_interface_router(
 
3946
-            '3e46229d-8fce-4733-819a-b5fe630550f8',
 
3947
-            {'subnet_id': '91e47a57-7508-46fe-afc9-fc454e8580e1'}
 
3948
-        ).AndReturn(None)
 
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)
 
3956
-
 
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'
 
3961
-            })
 
3962
-
 
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()
 
3967
-
 
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'}
 
3972
-        ).AndReturn(None)
 
3973
-        quantumclient.Client.remove_gateway_router(
 
3974
-            '3e46229d-8fce-4733-819a-b5fe630550f8'
 
3975
-        ).AndReturn(None)
 
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)
 
3982
-
 
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'
 
3987
-            })
 
3988
-
 
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()
 
3993
-
 
3994
-
 
3995
-@skipIf(quantumclient is None, 'quantumclient unavailable')
 
3996
-class QuantumFloatingIPTest(HeatTestCase):
 
3997
-    @skipIf(net.clients.quantumclient is None, "Missing Quantum Client")
 
3998
-    def setUp(self):
 
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')
 
4007
-        setup_dummy_db()
 
4008
-
 
4009
-    def test_floating_ip(self):
 
4010
-
 
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"
 
4016
-        }})
 
4017
-
 
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"
 
4026
-        }})
 
4027
-
 
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()
 
4034
-
 
4035
-        t = template_format.parse(quantum_floating_template)
 
4036
-        stack = parse_stack(t)
 
4037
-
 
4038
-        # assert the implicit dependency between the floating_ip
 
4039
-        # and the gateway
 
4040
-        deps = stack.dependencies[stack['gateway']]
 
4041
-        self.assertIn(stack['floating_ip'], deps)
 
4042
-
 
4043
-        fip = stack['floating_ip']
 
4044
-        scheduler.TaskRunner(fip.create)()
 
4045
-        self.assertEqual((fip.CREATE, fip.COMPLETE), fip.state)
 
4046
-        fip.validate()
 
4047
-
 
4048
-        fip_id = fip.FnGetRefId()
 
4049
-        self.assertEqual('fc68ea2c-b60b-4b4f-bd82-94ec81110766', fip_id)
 
4050
-
 
4051
-        self.assertEqual(None, fip.FnGetAtt('status'))
 
4052
-        self.assertEqual('ACTIVE', fip.FnGetAtt('status'))
 
4053
-        try:
 
4054
-            fip.FnGetAtt('Foo')
 
4055
-            raise Exception('Expected InvalidTemplateAttribute')
 
4056
-        except exception.InvalidTemplateAttribute:
 
4057
-            pass
 
4058
-
 
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)
 
4066
-
 
4067
-        self.m.VerifyAll()
 
4068
-
 
4069
-    def test_port(self):
 
4070
-
 
4071
-        quantumclient.Client.create_port({'port': {
 
4072
-            'network_id': u'xyz1234',
 
4073
-            'fixed_ips': [
 
4074
-                {'subnet_id': u'12.12.12.0', 'ip_address': u'10.0.0.10'}
 
4075
-            ],
 
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"
 
4081
-        }})
 
4082
-        quantumclient.Client.show_port(
 
4083
-            'fc68ea2c-b60b-4b4f-bd82-94ec81110766'
 
4084
-        ).AndReturn({'port': {
 
4085
-            "status": "BUILD",
 
4086
-            "id": "fc68ea2c-b60b-4b4f-bd82-94ec81110766"
 
4087
-        }})
 
4088
-        quantumclient.Client.show_port(
 
4089
-            'fc68ea2c-b60b-4b4f-bd82-94ec81110766'
 
4090
-        ).AndReturn({'port': {
 
4091
-            "status": "ACTIVE",
 
4092
-            "id": "fc68ea2c-b60b-4b4f-bd82-94ec81110766"
 
4093
-        }})
 
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"
 
4102
-        }})
 
4103
-
 
4104
-        self.m.ReplayAll()
 
4105
-
 
4106
-        t = template_format.parse(quantum_floating_template)
 
4107
-        stack = parse_stack(t)
 
4108
-
 
4109
-        p = stack['port_floating']
 
4110
-        scheduler.TaskRunner(p.create)()
 
4111
-        self.assertEqual((p.CREATE, p.COMPLETE), p.state)
 
4112
-        p.validate()
 
4113
-
 
4114
-        port_id = p.FnGetRefId()
 
4115
-        self.assertEqual('fc68ea2c-b60b-4b4f-bd82-94ec81110766', port_id)
 
4116
-
 
4117
-        self.assertEqual(None, p.FnGetAtt('status'))
 
4118
-        self.assertEqual('ACTIVE', p.FnGetAtt('status'))
 
4119
-        try:
 
4120
-            p.FnGetAtt('Foo')
 
4121
-            raise Exception('Expected InvalidTemplateAttribute')
 
4122
-        except exception.InvalidTemplateAttribute:
 
4123
-            pass
 
4124
-
 
4125
-        self.assertEqual('fc68ea2c-b60b-4b4f-bd82-94ec81110766',
 
4126
-                         p.FnGetAtt('id'))
 
4127
-
 
4128
-        self.assertRaises(resource.UpdateReplace,
 
4129
-                          p.handle_update, {}, {}, {})
 
4130
-
 
4131
-        self.m.VerifyAll()
 
4132
-
 
4133
-    def test_floatip_port(self):
 
4134
-
 
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"
 
4140
-        }})
 
4141
-
 
4142
-        quantumclient.Client.create_port({'port': {
 
4143
-            'network_id': u'xyz1234',
 
4144
-            'fixed_ips': [
 
4145
-                {'subnet_id': u'12.12.12.0', 'ip_address': u'10.0.0.10'}
 
4146
-            ],
 
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"
 
4152
-        }})
 
4153
-        quantumclient.Client.show_port(
 
4154
-            'fc68ea2c-b60b-4b4f-bd82-94ec81110766'
 
4155
-        ).AndReturn({'port': {
 
4156
-            "status": "ACTIVE",
 
4157
-            "id": "fc68ea2c-b60b-4b4f-bd82-94ec81110766"
 
4158
-        }})
 
4159
-        quantumclient.Client.update_floatingip(
 
4160
-            'fc68ea2c-b60b-4b4f-bd82-94ec81110766',
 
4161
-            {
 
4162
-                'floatingip': {
 
4163
-                    'port_id': u'fc68ea2c-b60b-4b4f-bd82-94ec81110766'}}
 
4164
-        ).AndReturn({'floatingip': {
 
4165
-            "status": "ACTIVE",
 
4166
-            "id": "fc68ea2c-b60b-4b4f-bd82-94ec81110766"
 
4167
-        }})
 
4168
-
 
4169
-        quantumclient.Client.update_floatingip(
 
4170
-            'fc68ea2c-b60b-4b4f-bd82-94ec81110766',
 
4171
-            {'floatingip': {
 
4172
-                'port_id': None
 
4173
-            }}).AndReturn(None)
 
4174
-
 
4175
-        quantumclient.Client.delete_port(
 
4176
-            'fc68ea2c-b60b-4b4f-bd82-94ec81110766'
 
4177
-        ).AndReturn(None)
 
4178
-
 
4179
-        quantumclient.Client.show_port(
 
4180
-            'fc68ea2c-b60b-4b4f-bd82-94ec81110766'
 
4181
-        ).AndRaise(qe.QuantumClientException(status_code=404))
 
4182
-
 
4183
-        quantumclient.Client.delete_floatingip(
 
4184
-            'fc68ea2c-b60b-4b4f-bd82-94ec81110766'
 
4185
-        ).AndReturn(None)
 
4186
-
 
4187
-        quantumclient.Client.update_floatingip(
 
4188
-            'fc68ea2c-b60b-4b4f-bd82-94ec81110766',
 
4189
-            {'floatingip': {
 
4190
-                'port_id': None
 
4191
-            }}).AndRaise(qe.QuantumClientException(status_code=404))
 
4192
-
 
4193
-        quantumclient.Client.delete_port(
 
4194
-            'fc68ea2c-b60b-4b4f-bd82-94ec81110766'
 
4195
-        ).AndRaise(qe.QuantumClientException(status_code=404))
 
4196
-
 
4197
-        quantumclient.Client.delete_floatingip(
 
4198
-            'fc68ea2c-b60b-4b4f-bd82-94ec81110766'
 
4199
-        ).AndRaise(qe.QuantumClientException(status_code=404))
 
4200
-
 
4201
-        self.m.ReplayAll()
 
4202
-
 
4203
-        t = template_format.parse(quantum_floating_template)
 
4204
-        stack = parse_stack(t)
 
4205
-
 
4206
-        fip = stack['floating_ip']
 
4207
-        scheduler.TaskRunner(fip.create)()
 
4208
-        self.assertEqual((fip.CREATE, fip.COMPLETE), fip.state)
 
4209
-
 
4210
-        p = stack['port_floating']
 
4211
-        scheduler.TaskRunner(p.create)()
 
4212
-        self.assertEqual((p.CREATE, p.COMPLETE), p.state)
 
4213
-
 
4214
-        fipa = stack['floating_ip_assoc']
 
4215
-        scheduler.TaskRunner(fipa.create)()
 
4216
-        self.assertEqual((fipa.CREATE, fipa.COMPLETE), fipa.state)
 
4217
-
 
4218
-        fipa.validate()
 
4219
-
 
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, {}, {}, {})
 
4226
-
 
4227
-        self.assertEqual(fipa.delete(), None)
 
4228
-        self.assertEqual(scheduler.TaskRunner(p.delete)(), None)
 
4229
-        self.assertEqual(fip.delete(), None)
 
4230
-
 
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')
 
4234
-
 
4235
-        self.assertEqual(fipa.delete(), None)
 
4236
-        self.assertEqual(scheduler.TaskRunner(p.delete)(), None)
 
4237
-        self.assertEqual(fip.delete(), None)
 
4238
-
 
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
 
4244
 
 
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
 
4251
 
 
4252
 NovaSG = collections.namedtuple('NovaSG',
 
4253
                                 ' '.join([
 
4254
@@ -59,7 +59,7 @@ Resources:
 
4255
           CidrIp : 0.0.0.0/0
 
4256
 '''
 
4257
 
 
4258
-    test_template_quantum = '''
 
4259
+    test_template_neutron = '''
 
4260
 HeatTemplateFormatVersion: '2012-12-12'
 
4261
 Resources:
 
4262
   the_sg:
 
4263
@@ -94,13 +94,13 @@ Resources:
 
4264
         self.m.StubOutWithMock(nova_sg.SecurityGroupManager, 'get')
 
4265
         self.m.StubOutWithMock(nova_sg.SecurityGroupManager, 'list')
 
4266
         setup_dummy_db()
 
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')
 
4279
 
 
4280
     def create_stack(self, template):
 
4281
         t = template_format.parse(template)
 
4282
@@ -278,10 +278,10 @@ Resources:
 
4283
         self.m.VerifyAll()
 
4284
 
 
4285
     @stack_delete_after
 
4286
-    def test_security_group_quantum(self):
 
4287
+    def test_security_group_neutron(self):
 
4288
         #create script
 
4289
         sg_name = utils.PhysName('test_stack', 'the_sg')
 
4290
-        quantumclient.Client.create_security_group({
 
4291
+        neutronclient.Client.create_security_group({
 
4292
             'security_group': {
 
4293
                 'name': sg_name,
 
4294
                 'description': 'HTTP and SSH access'
 
4295
@@ -296,7 +296,7 @@ Resources:
 
4296
             }
 
4297
         })
 
4298
 
 
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:
 
4305
                 'id': 'bbbb'
 
4306
             }
 
4307
         })
 
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:
 
4314
                 'id': 'cccc'
 
4315
             }
 
4316
         })
 
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:
 
4323
         })
 
4324
 
 
4325
         # delete script
 
4326
-        quantumclient.Client.show_security_group('aaaa').AndReturn({
 
4327
+        neutronclient.Client.show_security_group('aaaa').AndReturn({
 
4328
             'security_group': {
 
4329
                 'tenant_id': 'f18ca530cc05425e8bac0a5ff92f7e88',
 
4330
                 'name': 'sc1',
 
4331
@@ -401,13 +401,13 @@ Resources:
 
4332
                     'port_range_min': 22
 
4333
                 }],
 
4334
                 'id': 'aaaa'}})
 
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)
 
4343
 
 
4344
         self.m.ReplayAll()
 
4345
-        stack = self.create_stack(self.test_template_quantum)
 
4346
+        stack = self.create_stack(self.test_template_neutron)
 
4347
 
 
4348
         sg = stack['the_sg']
 
4349
         self.assertRaises(resource.UpdateReplace, sg.handle_update, {}, {}, {})
 
4350
@@ -418,10 +418,10 @@ Resources:
 
4351
         self.m.VerifyAll()
 
4352
 
 
4353
     @stack_delete_after
 
4354
-    def test_security_group_quantum_exception(self):
 
4355
+    def test_security_group_neutron_exception(self):
 
4356
         #create script
 
4357
         sg_name = utils.PhysName('test_stack', 'the_sg')
 
4358
-        quantumclient.Client.create_security_group({
 
4359
+        neutronclient.Client.create_security_group({
 
4360
             'security_group': {
 
4361
                 'name': sg_name,
 
4362
                 'description': 'HTTP and SSH access'
 
4363
@@ -436,7 +436,7 @@ Resources:
 
4364
             }
 
4365
         })
 
4366
 
 
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'
 
4374
             }
 
4375
         }).AndRaise(
 
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'
 
4385
             }
 
4386
         }).AndRaise(
 
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'
 
4396
             }
 
4397
         }).AndRaise(
 
4398
-            QuantumClientException(status_code=409))
 
4399
+            NeutronClientException(status_code=409))
 
4400
 
 
4401
         # delete script
 
4402
-        quantumclient.Client.show_security_group('aaaa').AndReturn({
 
4403
+        neutronclient.Client.show_security_group('aaaa').AndReturn({
 
4404
             'security_group': {
 
4405
                 'tenant_id': 'f18ca530cc05425e8bac0a5ff92f7e88',
 
4406
                 'name': 'sc1',
 
4407
@@ -511,20 +511,20 @@ Resources:
 
4408
                     'port_range_min': 22
 
4409
                 }],
 
4410
                 'id': 'aaaa'}})
 
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))
 
4427
 
 
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))
 
4432
 
 
4433
         self.m.ReplayAll()
 
4434
-        stack = self.create_stack(self.test_template_quantum)
 
4435
+        stack = self.create_stack(self.test_template_neutron)
 
4436
 
 
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)
 
4445
 
 
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', {})
 
4452
 
 
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
 
4460
 
 
4461
 try:
 
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
 
4466
 except ImportError:
 
4467
-    quantumclient = None
 
4468
+    neutronclient = None
 
4469
 
 
4470
 
 
4471
 class VPCTestBase(HeatTestCase):
 
4472
 
 
4473
-    @skipIf(quantumclient is None, 'quantumclient unavaialble')
 
4474
+    @skipIf(neutronclient is None, 'neutronclient unavaialble')
 
4475
     def setUp(self):
 
4476
         super(VPCTestBase, self).setUp()
 
4477
         setup_dummy_db()
 
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')
 
4524
 
 
4525
     def create_stack(self, template):
 
4526
         t = template_format.parse(template)
 
4527
@@ -81,7 +81,7 @@ class VPCTestBase(HeatTestCase):
 
4528
 
 
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(
 
4533
             {
 
4534
                 'network': {'name': self.vpc_name}
 
4535
             }).AndReturn({'network': {
 
4536
@@ -93,7 +93,7 @@ class VPCTestBase(HeatTestCase):
 
4537
                 'tenant_id': 'c1210485b2424d48804aad5d39c61b8f',
 
4538
                 'id': 'aaaa'
 
4539
             }})
 
4540
-        quantumclient.Client.show_network(
 
4541
+        neutronclient.Client.show_network(
 
4542
             'aaaa'
 
4543
         ).AndReturn({"network": {
 
4544
             "status": "BUILD",
 
4545
@@ -105,7 +105,7 @@ class VPCTestBase(HeatTestCase):
 
4546
             "id": "aaaa"
 
4547
         }})
 
4548
 
 
4549
-        quantumclient.Client.show_network(
 
4550
+        neutronclient.Client.show_network(
 
4551
             'aaaa'
 
4552
         ).MultipleTimes().AndReturn({"network": {
 
4553
             "status": "ACTIVE",
 
4554
@@ -116,7 +116,7 @@ class VPCTestBase(HeatTestCase):
 
4555
             "tenant_id": "c1210485b2424d48804aad5d39c61b8f",
 
4556
             "id": "aaaa"
 
4557
         }})
 
4558
-        quantumclient.Client.create_router(
 
4559
+        neutronclient.Client.create_router(
 
4560
             {'router': {'name': self.vpc_name}}).AndReturn({
 
4561
                 'router': {
 
4562
                     'status': 'BUILD',
 
4563
@@ -125,7 +125,7 @@ class VPCTestBase(HeatTestCase):
 
4564
                     'tenant_id': 'c1210485b2424d48804aad5d39c61b8f',
 
4565
                     'id': 'bbbb'
 
4566
                 }})
 
4567
-        quantumclient.Client.list_routers(name=self.vpc_name).AndReturn({
 
4568
+        neutronclient.Client.list_routers(name=self.vpc_name).AndReturn({
 
4569
             "routers": [{
 
4570
                 "status": "BUILD",
 
4571
                 "external_gateway_info": None,
 
4572
@@ -140,7 +140,7 @@ class VPCTestBase(HeatTestCase):
 
4573
 
 
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(
 
4578
             {'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',
 
4583
                         'id': 'cccc'}})
 
4584
         self.mock_router_for_vpc()
 
4585
-        quantumclient.Client.add_interface_router(
 
4586
+        neutronclient.Client.add_interface_router(
 
4587
             u'bbbb',
 
4588
             {'subnet_id': 'cccc'}).AndReturn(None)
 
4589
 
 
4590
     def mock_show_subnet(self):
 
4591
-        quantumclient.Client.show_subnet('cccc').AndReturn({
 
4592
+        neutronclient.Client.show_subnet('cccc').AndReturn({
 
4593
             'subnet': {
 
4594
                 'name': self.subnet_name,
 
4595
                 'network_id': 'aaaa',
 
4596
@@ -174,7 +174,7 @@ class VPCTestBase(HeatTestCase):
 
4597
 
 
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({
 
4602
             'security_group': {
 
4603
                 'name': self.sg_name,
 
4604
                 'description': 'SSH access'
 
4605
@@ -189,7 +189,7 @@ class VPCTestBase(HeatTestCase):
 
4606
             }
 
4607
         })
 
4608
 
 
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):
 
4615
 
 
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({
 
4620
             'security_group': {
 
4621
                 'tenant_id': 'c1210485b2424d48804aad5d39c61b8f',
 
4622
                 'name': sg_name,
 
4623
@@ -231,11 +231,11 @@ class VPCTestBase(HeatTestCase):
 
4624
                     'port_range_min': 22
 
4625
                 }],
 
4626
                 'id': 'eeee'}})
 
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)
 
4631
 
 
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({
 
4635
             "routers": [{
 
4636
                 "status": "ACTIVE",
 
4637
                 "external_gateway_info": {
 
4638
@@ -251,19 +251,19 @@ class VPCTestBase(HeatTestCase):
 
4639
 
 
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)
 
4646
 
 
4647
     def mock_delete_subnet(self):
 
4648
         self.mock_router_for_vpc()
 
4649
-        quantumclient.Client.remove_interface_router(
 
4650
+        neutronclient.Client.remove_interface_router(
 
4651
             u'bbbb',
 
4652
             {'subnet_id': 'cccc'}).AndReturn(None)
 
4653
-        quantumclient.Client.delete_subnet('cccc').AndReturn(None)
 
4654
+        neutronclient.Client.delete_subnet('cccc').AndReturn(None)
 
4655
 
 
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({
 
4661
                 'router': {
 
4662
                     'status': 'BUILD',
 
4663
@@ -273,7 +273,7 @@ class VPCTestBase(HeatTestCase):
 
4664
                     'id': 'ffff'
 
4665
                 }
 
4666
             })
 
4667
-        quantumclient.Client.show_router('ffff').AndReturn({
 
4668
+        neutronclient.Client.show_router('ffff').AndReturn({
 
4669
             'router': {
 
4670
                 'status': 'BUILD',
 
4671
                 'name': self.rt_name,
 
4672
@@ -282,7 +282,7 @@ class VPCTestBase(HeatTestCase):
 
4673
                 'id': 'ffff'
 
4674
             }
 
4675
         })
 
4676
-        quantumclient.Client.show_router('ffff').AndReturn({
 
4677
+        neutronclient.Client.show_router('ffff').AndReturn({
 
4678
             'router': {
 
4679
                 'status': 'ACTIVE',
 
4680
                 'name': self.rt_name,
 
4681
@@ -292,32 +292,32 @@ class VPCTestBase(HeatTestCase):
 
4682
             }
 
4683
         })
 
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)
 
4688
 
 
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(
 
4694
             'bbbb',
 
4695
             {'subnet_id': u'cccc'}).AndReturn(None)
 
4696
-        quantumclient.Client.add_interface_router(
 
4697
+        neutronclient.Client.add_interface_router(
 
4698
             u'ffff',
 
4699
             {'subnet_id': 'cccc'}).AndReturn(None)
 
4700
 
 
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(
 
4706
             'ffff',
 
4707
             {'subnet_id': u'cccc'}).AndReturn(None)
 
4708
-        quantumclient.Client.add_interface_router(
 
4709
+        neutronclient.Client.add_interface_router(
 
4710
             u'bbbb',
 
4711
             {'subnet_id': 'cccc'}).AndReturn(None)
 
4712
 
 
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)
 
4718
 
 
4719
     def assertResourceState(self, resource, ref_id):
 
4720
         self.assertEqual(None, resource.validate())
 
4721
@@ -374,12 +374,12 @@ Resources:
 
4722
 
 
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(
 
4727
             u'bbbb',
 
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))
 
4735
 
 
4736
         self.m.ReplayAll()
 
4737
         stack = self.create_stack(self.test_template)
 
4738
@@ -519,7 +519,7 @@ Resources:
 
4739
         if security_groups:
 
4740
                 port['security_groups'] = security_groups
 
4741
 
 
4742
-        quantumclient.Client.create_port({'port': port}).AndReturn({
 
4743
+        neutronclient.Client.create_port({'port': port}).AndReturn({
 
4744
             'port': {
 
4745
                 'admin_state_up': True,
 
4746
                 'device_id': '',
 
4747
@@ -540,7 +540,7 @@ Resources:
 
4748
         })
 
4749
 
 
4750
     def mock_delete_network_interface(self):
 
4751
-        quantumclient.Client.delete_port('dddd').AndReturn(None)
 
4752
+        neutronclient.Client.delete_port('dddd').AndReturn(None)
 
4753
 
 
4754
     def test_network_interface(self):
 
4755
         self.mock_create_security_group()
 
4756
@@ -652,7 +652,7 @@ Resources:
 
4757
 '''
 
4758
 
 
4759
     def mock_create_internet_gateway(self):
 
4760
-        quantumclient.Client.list_networks(
 
4761
+        neutronclient.Client.list_networks(
 
4762
             **{'router:external': True}).AndReturn({'networks': [{
 
4763
                 'status': 'ACTIVE',
 
4764
                 'subnets': [],
 
4765
@@ -665,11 +665,11 @@ Resources:
 
4766
             }]})
 
4767
 
 
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)
 
4772
 
 
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)
 
4776
 
 
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
 
4792
 WebOb==1.2.3
 
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
 
4798
 PyYAML>=3.1.0
 
4799
 oslo.config>=1.1.0