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

« back to all changes in this revision

Viewing changes to heat/tests/test_vpc.py

  • Committer: Package Import Robot
  • Author(s): Chuck Short, Yolanda Robla, Chuck Short
  • Date: 2013-07-22 16:22:29 UTC
  • mfrom: (1.1.2)
  • Revision ID: package-import@ubuntu.com-20130722162229-zzvfu40id94ii0hc
Tags: 2013.2~b2-0ubuntu1
[ Yolanda Robla ]
* debian/tests: added autopkg tests

[ Chuck Short ]
* New upstream release
* debian/control:
  - Add python-pbr to build-depends.
  - Add python-d2to to build-depends.
  - Dropped python-argparse.
  - Add python-six to build-depends.
  - Dropped python-sendfile.
  - Dropped python-nose.
  - Added testrepository.
  - Added python-testtools.
* debian/rules: Run testrepository instead of nosetets.
* debian/patches/removes-lxml-version-limitation-from-pip-requires.patch: Dropped
  no longer needed.
* debian/patches/fix-package-version-detection-when-building-doc.patch: Dropped
  no longer needed.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
# vim: tabstop=4 shiftwidth=4 softtabstop=4
2
2
 
3
 
#    Licensed under the Apache License, Version 2.0 (the 'License"); you may
 
3
#    Licensed under the Apache License, Version 2.0 (the "License"); you may
4
4
#    not use this file except in compliance with the License. You may obtain
5
5
#    a copy of the License at
6
6
#
12
12
#    License for the specific language governing permissions and limitations
13
13
#    under the License.
14
14
 
15
 
 
16
 
import unittest
17
 
import mox
18
 
 
19
 
from nose.plugins.attrib import attr
 
15
from testtools import skipIf
20
16
 
21
17
from heat.common import context
22
18
from heat.common import exception
23
19
from heat.common import template_format
24
20
from heat.engine import parser
25
 
import heat.engine.resources  # pyflakes_bypass review 23102
 
21
from heat.engine import resource
 
22
from heat.tests.common import HeatTestCase
 
23
from heat.tests import utils
 
24
from heat.tests.utils import setup_dummy_db
26
25
 
27
26
try:
28
27
    from quantumclient.common.exceptions import QuantumClientException
29
28
    from quantumclient.v2_0 import client as quantumclient
30
29
except ImportError:
31
 
    from nose.exc import SkipTest
32
 
    raise SkipTest()
33
 
 
34
 
 
35
 
class VPCTestBase(unittest.TestCase):
36
 
 
 
30
    quantumclient = None
 
31
 
 
32
 
 
33
class VPCTestBase(HeatTestCase):
 
34
 
 
35
    @skipIf(quantumclient is None, 'quantumclient unavaialble')
37
36
    def setUp(self):
38
 
        self.m = mox.Mox()
 
37
        super(VPCTestBase, self).setUp()
 
38
        setup_dummy_db()
39
39
        self.m.StubOutWithMock(quantumclient.Client, 'add_interface_router')
40
40
        self.m.StubOutWithMock(quantumclient.Client, 'add_gateway_router')
41
41
        self.m.StubOutWithMock(quantumclient.Client, 'create_network')
47
47
        self.m.StubOutWithMock(quantumclient.Client, 'delete_router')
48
48
        self.m.StubOutWithMock(quantumclient.Client, 'delete_subnet')
49
49
        self.m.StubOutWithMock(quantumclient.Client, 'list_networks')
 
50
        self.m.StubOutWithMock(quantumclient.Client, 'list_routers')
50
51
        self.m.StubOutWithMock(quantumclient.Client, 'remove_gateway_router')
51
52
        self.m.StubOutWithMock(quantumclient.Client, 'remove_interface_router')
52
53
        self.m.StubOutWithMock(quantumclient.Client, 'show_subnet')
53
54
        self.m.StubOutWithMock(quantumclient.Client, 'show_network')
54
 
 
55
 
    def tearDown(self):
56
 
        self.m.UnsetStubs()
 
55
        self.m.StubOutWithMock(quantumclient.Client, 'show_router')
 
56
        self.m.StubOutWithMock(quantumclient.Client, 'create_security_group')
 
57
        self.m.StubOutWithMock(quantumclient.Client, 'show_security_group')
 
58
        self.m.StubOutWithMock(quantumclient.Client, 'delete_security_group')
 
59
        self.m.StubOutWithMock(
 
60
            quantumclient.Client, 'create_security_group_rule')
 
61
        self.m.StubOutWithMock(
 
62
            quantumclient.Client, 'delete_security_group_rule')
57
63
 
58
64
    def create_stack(self, template):
59
65
        t = template_format.parse(template)
69
75
            'auth_url': 'http://localhost:5000/v2.0'})
70
76
        stack_name = 'test_stack'
71
77
        tmpl = parser.Template(t)
72
 
        params = parser.Parameters(stack_name, tmpl, {})
73
 
        stack = parser.Stack(ctx, stack_name, tmpl, params)
 
78
        stack = parser.Stack(ctx, stack_name, tmpl)
74
79
        stack.store()
75
80
        return stack
76
81
 
77
82
    def mock_create_network(self):
 
83
        self.vpc_name = utils.PhysName('test_stack', 'the_vpc')
78
84
        quantumclient.Client.create_network(
79
85
            {
80
 
                'network': {'name': 'test_stack.the_vpc'}
 
86
                'network': {'name': self.vpc_name}
81
87
            }).AndReturn({'network': {
82
 
                'status': 'ACTIVE',
 
88
                'status': 'BUILD',
83
89
                'subnets': [],
84
90
                'name': 'name',
85
91
                'admin_state_up': True,
87
93
                'tenant_id': 'c1210485b2424d48804aad5d39c61b8f',
88
94
                'id': 'aaaa'
89
95
            }})
 
96
        quantumclient.Client.show_network(
 
97
            'aaaa'
 
98
        ).AndReturn({"network": {
 
99
            "status": "BUILD",
 
100
            "subnets": [],
 
101
            "name": self.vpc_name,
 
102
            "admin_state_up": False,
 
103
            "shared": False,
 
104
            "tenant_id": "c1210485b2424d48804aad5d39c61b8f",
 
105
            "id": "aaaa"
 
106
        }})
 
107
 
 
108
        quantumclient.Client.show_network(
 
109
            'aaaa'
 
110
        ).MultipleTimes().AndReturn({"network": {
 
111
            "status": "ACTIVE",
 
112
            "subnets": [],
 
113
            "name": self.vpc_name,
 
114
            "admin_state_up": False,
 
115
            "shared": False,
 
116
            "tenant_id": "c1210485b2424d48804aad5d39c61b8f",
 
117
            "id": "aaaa"
 
118
        }})
90
119
        quantumclient.Client.create_router(
91
 
            {'router': {'name': 'test_stack.the_vpc'}}).AndReturn({'router': {
92
 
                'status': 'ACTIVE',
93
 
                'name': 'name',
94
 
                'admin_state_up': True,
95
 
                'tenant_id': 'c1210485b2424d48804aad5d39c61b8f',
96
 
                'id': 'bbbb'
97
 
            }})
 
120
            {'router': {'name': self.vpc_name}}).AndReturn({
 
121
                'router': {
 
122
                    'status': 'BUILD',
 
123
                    'name': self.vpc_name,
 
124
                    'admin_state_up': True,
 
125
                    'tenant_id': 'c1210485b2424d48804aad5d39c61b8f',
 
126
                    'id': 'bbbb'
 
127
                }})
 
128
        quantumclient.Client.list_routers(name=self.vpc_name).AndReturn({
 
129
            "routers": [{
 
130
                "status": "BUILD",
 
131
                "external_gateway_info": None,
 
132
                "name": self.vpc_name,
 
133
                "admin_state_up": True,
 
134
                "tenant_id": "3e21026f2dc94372b105808c0e721661",
 
135
                "routes": [],
 
136
                "id": "bbbb"
 
137
            }]
 
138
        })
 
139
        self.mock_router_for_vpc()
98
140
 
99
141
    def mock_create_subnet(self):
 
142
        self.subnet_name = utils.PhysName('test_stack', 'the_subnet')
100
143
        quantumclient.Client.create_subnet(
101
144
            {'subnet': {
102
145
                'network_id': u'aaaa',
103
146
                'cidr': u'10.0.0.0/24',
104
147
                'ip_version': 4,
105
 
                'name': u'test_stack.the_subnet'}}).AndReturn({
 
148
                'name': self.subnet_name}}).AndReturn({
106
149
                    'subnet': {
107
150
                        'status': 'ACTIVE',
108
 
                        'name': 'test_stack.the_subnet',
 
151
                        'name': self.subnet_name,
109
152
                        'admin_state_up': True,
110
153
                        'tenant_id': 'c1210485b2424d48804aad5d39c61b8f',
111
154
                        'id': 'cccc'}})
 
155
        self.mock_router_for_vpc()
112
156
        quantumclient.Client.add_interface_router(
113
157
            u'bbbb',
114
158
            {'subnet_id': 'cccc'}).AndReturn(None)
115
159
 
 
160
    def mock_show_subnet(self):
 
161
        quantumclient.Client.show_subnet('cccc').AndReturn({
 
162
            'subnet': {
 
163
                'name': self.subnet_name,
 
164
                'network_id': 'aaaa',
 
165
                'tenant_id': 'c1210485b2424d48804aad5d39c61b8f',
 
166
                'allocation_pools': [{'start': '10.0.0.2',
 
167
                                      'end': '10.0.0.254'}],
 
168
                'gateway_ip': '10.0.0.1',
 
169
                'ip_version': 4,
 
170
                'cidr': '10.0.0.0/24',
 
171
                'id': 'cccc',
 
172
                'enable_dhcp': False,
 
173
            }})
 
174
 
 
175
    def mock_create_security_group(self):
 
176
        self.sg_name = utils.PhysName('test_stack', 'the_sg')
 
177
        quantumclient.Client.create_security_group({
 
178
            'security_group': {
 
179
                'name': self.sg_name,
 
180
                'description': 'SSH access'
 
181
            }
 
182
        }).AndReturn({
 
183
            'security_group': {
 
184
                'tenant_id': 'c1210485b2424d48804aad5d39c61b8f',
 
185
                'name': self.sg_name,
 
186
                'description': 'SSH access',
 
187
                'security_group_rules': [],
 
188
                'id': 'eeee'
 
189
            }
 
190
        })
 
191
 
 
192
        quantumclient.Client.create_security_group_rule({
 
193
            'security_group_rule': {
 
194
                'direction': 'ingress',
 
195
                'remote_ip_prefix': '0.0.0.0/0',
 
196
                'port_range_min': 22,
 
197
                'ethertype': 'IPv4',
 
198
                'port_range_max': 22,
 
199
                'protocol': 'tcp',
 
200
                'security_group_id': 'eeee'
 
201
            }
 
202
        }).AndReturn({
 
203
            'security_group_rule': {
 
204
                'direction': 'ingress',
 
205
                'remote_ip_prefix': '0.0.0.0/0',
 
206
                'port_range_min': 22,
 
207
                'ethertype': 'IPv4',
 
208
                'port_range_max': 22,
 
209
                'protocol': 'tcp',
 
210
                'security_group_id': 'eeee',
 
211
                'id': 'bbbb'
 
212
            }
 
213
        })
 
214
 
 
215
    def mock_delete_security_group(self):
 
216
        sg_name = utils.PhysName('test_stack', 'the_sg')
 
217
        quantumclient.Client.show_security_group('eeee').AndReturn({
 
218
            'security_group': {
 
219
                'tenant_id': 'c1210485b2424d48804aad5d39c61b8f',
 
220
                'name': sg_name,
 
221
                'description': '',
 
222
                'security_group_rules': [{
 
223
                    'direction': 'ingress',
 
224
                    'protocol': 'tcp',
 
225
                    'port_range_max': 22,
 
226
                    'id': 'bbbb',
 
227
                    'ethertype': 'IPv4',
 
228
                    'security_group_id': 'eeee',
 
229
                    'remote_ip_prefix': '0.0.0.0/0',
 
230
                    'tenant_id': 'c1210485b2424d48804aad5d39c61b8f',
 
231
                    'port_range_min': 22
 
232
                }],
 
233
                'id': 'eeee'}})
 
234
        quantumclient.Client.delete_security_group_rule('bbbb').AndReturn(None)
 
235
        quantumclient.Client.delete_security_group('eeee').AndReturn(None)
 
236
 
 
237
    def mock_router_for_vpc(self):
 
238
        quantumclient.Client.list_routers(name=self.vpc_name).AndReturn({
 
239
            "routers": [{
 
240
                "status": "ACTIVE",
 
241
                "external_gateway_info": {
 
242
                    "network_id": "zzzz",
 
243
                    "enable_snat": True},
 
244
                "name": self.vpc_name,
 
245
                "admin_state_up": True,
 
246
                "tenant_id": "3e21026f2dc94372b105808c0e721661",
 
247
                "routes": [],
 
248
                "id": "bbbb"
 
249
            }]
 
250
        })
 
251
 
116
252
    def mock_delete_network(self):
 
253
        self.mock_router_for_vpc()
117
254
        quantumclient.Client.delete_router('bbbb').AndReturn(None)
118
255
        quantumclient.Client.delete_network('aaaa').AndReturn(None)
119
256
 
120
257
    def mock_delete_subnet(self):
 
258
        self.mock_router_for_vpc()
121
259
        quantumclient.Client.remove_interface_router(
122
260
            u'bbbb',
123
261
            {'subnet_id': 'cccc'}).AndReturn(None)
124
262
        quantumclient.Client.delete_subnet('cccc').AndReturn(None)
125
263
 
126
 
    def assertResourceState(self, resource, ref_id, metadata={}):
 
264
    def mock_create_route_table(self):
 
265
        self.rt_name = utils.PhysName('test_stack', 'the_route_table')
 
266
        quantumclient.Client.create_router({
 
267
            'router': {'name': self.rt_name}}).AndReturn({
 
268
                'router': {
 
269
                    'status': 'BUILD',
 
270
                    'name': self.rt_name,
 
271
                    'admin_state_up': True,
 
272
                    'tenant_id': 'c1210485b2424d48804aad5d39c61b8f',
 
273
                    'id': 'ffff'
 
274
                }
 
275
            })
 
276
        quantumclient.Client.show_router('ffff').AndReturn({
 
277
            'router': {
 
278
                'status': 'BUILD',
 
279
                'name': self.rt_name,
 
280
                'admin_state_up': True,
 
281
                'tenant_id': 'c1210485b2424d48804aad5d39c61b8f',
 
282
                'id': 'ffff'
 
283
            }
 
284
        })
 
285
        quantumclient.Client.show_router('ffff').AndReturn({
 
286
            'router': {
 
287
                'status': 'ACTIVE',
 
288
                'name': self.rt_name,
 
289
                'admin_state_up': True,
 
290
                'tenant_id': 'c1210485b2424d48804aad5d39c61b8f',
 
291
                'id': 'ffff'
 
292
            }
 
293
        })
 
294
        self.mock_router_for_vpc()
 
295
        quantumclient.Client.add_gateway_router(
 
296
            'ffff', {'network_id': 'zzzz'}).AndReturn(None)
 
297
 
 
298
    def mock_create_association(self):
 
299
        self.mock_show_subnet()
 
300
        self.mock_router_for_vpc()
 
301
        quantumclient.Client.remove_interface_router(
 
302
            'bbbb',
 
303
            {'subnet_id': u'cccc'}).AndReturn(None)
 
304
        quantumclient.Client.add_interface_router(
 
305
            u'ffff',
 
306
            {'subnet_id': 'cccc'}).AndReturn(None)
 
307
 
 
308
    def mock_delete_association(self):
 
309
        self.mock_show_subnet()
 
310
        self.mock_router_for_vpc()
 
311
        quantumclient.Client.remove_interface_router(
 
312
            'ffff',
 
313
            {'subnet_id': u'cccc'}).AndReturn(None)
 
314
        quantumclient.Client.add_interface_router(
 
315
            u'bbbb',
 
316
            {'subnet_id': 'cccc'}).AndReturn(None)
 
317
 
 
318
    def mock_delete_route_table(self):
 
319
        quantumclient.Client.delete_router('ffff').AndReturn(None)
 
320
        quantumclient.Client.remove_gateway_router('ffff').AndReturn(None)
 
321
 
 
322
    def assertResourceState(self, resource, ref_id):
127
323
        self.assertEqual(None, resource.validate())
128
 
        self.assertEqual(resource.CREATE_COMPLETE, resource.state)
 
324
        self.assertEqual((resource.CREATE, resource.COMPLETE), resource.state)
129
325
        self.assertEqual(ref_id, resource.FnGetRefId())
130
 
        self.assertEqual(metadata, dict(resource.metadata))
131
 
 
132
 
 
133
 
@attr(tag=['unit', 'resource'])
134
 
@attr(speed='fast')
 
326
 
 
327
 
135
328
class VPCTest(VPCTestBase):
136
329
 
137
330
    test_template = '''
148
341
        self.m.ReplayAll()
149
342
 
150
343
        stack = self.create_stack(self.test_template)
151
 
        resource = stack['the_vpc']
152
 
        self.assertResourceState(resource, 'aaaa', {
153
 
            'router_id': 'bbbb',
154
 
            'all_router_ids': ['bbbb']})
155
 
        self.assertEqual(resource.UPDATE_REPLACE, resource.handle_update({}))
 
344
        vpc = stack['the_vpc']
 
345
        self.assertResourceState(vpc, 'aaaa')
 
346
        self.assertRaises(resource.UpdateReplace,
 
347
                          vpc.handle_update, {}, {}, {})
156
348
 
157
 
        self.assertEqual(None, resource.delete())
 
349
        self.assertEqual(None, vpc.delete())
158
350
        self.m.VerifyAll()
159
351
 
160
352
 
161
 
@attr(tag=['unit', 'resource'])
162
 
@attr(speed='fast')
163
353
class SubnetTest(VPCTestBase):
164
354
 
165
355
    test_template = '''
183
373
        self.mock_delete_network()
184
374
 
185
375
        # mock delete subnet which is already deleted
 
376
        self.mock_router_for_vpc()
186
377
        quantumclient.Client.remove_interface_router(
187
378
            u'bbbb',
188
379
            {'subnet_id': 'cccc'}).AndRaise(
193
384
        self.m.ReplayAll()
194
385
        stack = self.create_stack(self.test_template)
195
386
 
196
 
        resource = stack['the_subnet']
197
 
        self.assertResourceState(resource, 'cccc', {
198
 
            'router_id': 'bbbb',
199
 
            'default_router_id': 'bbbb'})
 
387
        subnet = stack['the_subnet']
 
388
        self.assertResourceState(subnet, 'cccc')
200
389
 
201
 
        self.assertEqual(resource.UPDATE_REPLACE, resource.handle_update({}))
 
390
        self.assertRaises(resource.UpdateReplace,
 
391
                          subnet.handle_update, {}, {}, {})
202
392
        self.assertRaises(
203
393
            exception.InvalidTemplateAttribute,
204
 
            resource.FnGetAtt,
 
394
            subnet.FnGetAtt,
205
395
            'Foo')
206
396
 
207
 
        self.assertEqual('moon', resource.FnGetAtt('AvailabilityZone'))
 
397
        self.assertEqual('moon', subnet.FnGetAtt('AvailabilityZone'))
208
398
 
209
 
        self.assertEqual(None, resource.delete())
210
 
        resource.state_set(resource.CREATE_COMPLETE, 'to delete again')
211
 
        self.assertEqual(None, resource.delete())
 
399
        self.assertEqual(None, subnet.delete())
 
400
        subnet.state_set(subnet.CREATE, subnet.COMPLETE, 'to delete again')
 
401
        self.assertEqual(None, subnet.delete())
212
402
        self.assertEqual(None, stack['the_vpc'].delete())
213
403
        self.m.VerifyAll()
214
404
 
215
405
 
216
 
@attr(tag=['unit', 'resource'])
217
 
@attr(speed='fast')
218
406
class NetworkInterfaceTest(VPCTestBase):
219
407
 
220
408
    test_template = '''
221
409
HeatTemplateFormatVersion: '2012-12-12'
222
410
Resources:
223
 
  the_vpc:
224
 
    Type: AWS::EC2::VPC
225
 
    Properties: {CidrBlock: '10.0.0.0/16'}
226
 
  the_subnet:
227
 
    Type: AWS::EC2::Subnet
228
 
    Properties:
229
 
      CidrBlock: 10.0.0.0/24
230
 
      VpcId: {Ref: the_vpc}
231
 
      AvailabilityZone: moon
232
 
  the_nic:
233
 
    Type: AWS::EC2::NetworkInterface
234
 
    Properties:
235
 
      PrivateIpAddress: 10.0.0.100
236
 
      SubnetId: {Ref: the_subnet}
237
 
'''
238
 
 
239
 
    def mock_create_network_interface(self):
240
 
        quantumclient.Client.create_port({
241
 
            'port': {
242
 
                'network_id': 'aaaa', 'fixed_ips': [{
 
411
  the_sg:
 
412
    Type: AWS::EC2::SecurityGroup
 
413
    Properties:
 
414
      VpcId: {Ref: the_vpc}
 
415
      GroupDescription: SSH access
 
416
      SecurityGroupIngress:
 
417
        - IpProtocol: tcp
 
418
          FromPort: 22
 
419
          ToPort: 22
 
420
          CidrIp: 0.0.0.0/0
 
421
  the_vpc:
 
422
    Type: AWS::EC2::VPC
 
423
    Properties: {CidrBlock: '10.0.0.0/16'}
 
424
  the_subnet:
 
425
    Type: AWS::EC2::Subnet
 
426
    Properties:
 
427
      CidrBlock: 10.0.0.0/24
 
428
      VpcId: {Ref: the_vpc}
 
429
      AvailabilityZone: moon
 
430
  the_nic:
 
431
    Type: AWS::EC2::NetworkInterface
 
432
    Properties:
 
433
      PrivateIpAddress: 10.0.0.100
 
434
      SubnetId: {Ref: the_subnet}
 
435
      GroupSet:
 
436
      - Ref: the_sg
 
437
'''
 
438
 
 
439
    test_template_no_groupset = '''
 
440
HeatTemplateFormatVersion: '2012-12-12'
 
441
Resources:
 
442
  the_vpc:
 
443
    Type: AWS::EC2::VPC
 
444
    Properties: {CidrBlock: '10.0.0.0/16'}
 
445
  the_subnet:
 
446
    Type: AWS::EC2::Subnet
 
447
    Properties:
 
448
      CidrBlock: 10.0.0.0/24
 
449
      VpcId: {Ref: the_vpc}
 
450
      AvailabilityZone: moon
 
451
  the_nic:
 
452
    Type: AWS::EC2::NetworkInterface
 
453
    Properties:
 
454
      PrivateIpAddress: 10.0.0.100
 
455
      SubnetId: {Ref: the_subnet}
 
456
'''
 
457
 
 
458
    test_template_error = '''
 
459
HeatTemplateFormatVersion: '2012-12-12'
 
460
Resources:
 
461
  the_sg:
 
462
    Type: AWS::EC2::SecurityGroup
 
463
    Properties:
 
464
      VpcId: {Ref: the_vpc}
 
465
      GroupDescription: SSH access
 
466
      SecurityGroupIngress:
 
467
        - IpProtocol: tcp
 
468
          FromPort: 22
 
469
          ToPort: 22
 
470
          CidrIp: 0.0.0.0/0
 
471
  the_vpc:
 
472
    Type: AWS::EC2::VPC
 
473
    Properties: {CidrBlock: '10.0.0.0/16'}
 
474
  the_subnet:
 
475
    Type: AWS::EC2::Subnet
 
476
    Properties:
 
477
      CidrBlock: 10.0.0.0/24
 
478
      VpcId: {Ref: the_vpc}
 
479
      AvailabilityZone: moon
 
480
  the_nic:
 
481
    Type: AWS::EC2::NetworkInterface
 
482
    Properties:
 
483
      PrivateIpAddress: 10.0.0.100
 
484
      SubnetId: {Ref: the_subnet}
 
485
      GroupSet:
 
486
      - Ref: INVALID-REF-IN-TEMPLATE
 
487
'''
 
488
 
 
489
    test_template_error_no_ref = '''
 
490
HeatTemplateFormatVersion: '2012-12-12'
 
491
Resources:
 
492
  the_vpc:
 
493
    Type: AWS::EC2::VPC
 
494
    Properties: {CidrBlock: '10.0.0.0/16'}
 
495
  the_subnet:
 
496
    Type: AWS::EC2::Subnet
 
497
    Properties:
 
498
      CidrBlock: 10.0.0.0/24
 
499
      VpcId: {Ref: the_vpc}
 
500
      AvailabilityZone: moon
 
501
  the_nic:
 
502
    Type: AWS::EC2::NetworkInterface
 
503
    Properties:
 
504
      PrivateIpAddress: 10.0.0.100
 
505
      SubnetId: {Ref: the_subnet}
 
506
      GroupSet:
 
507
      - INVALID-NO-REF
 
508
'''
 
509
 
 
510
    def mock_create_network_interface(self, security_groups=['eeee']):
 
511
        self.nic_name = utils.PhysName('test_stack', 'the_nic')
 
512
        port = {'network_id': 'aaaa',
 
513
                'fixed_ips': [{
243
514
                    'subnet_id': u'cccc',
244
515
                    'ip_address': u'10.0.0.100'
245
516
                }],
246
 
                'name': u'test_stack.the_nic',
247
 
                'admin_state_up': True
248
 
            }}).AndReturn({
249
 
                'port': {
250
 
                    'admin_state_up': True,
251
 
                    'device_id': '',
252
 
                    'device_owner': '',
253
 
                    'fixed_ips': [
254
 
                        {
255
 
                            'ip_address': '10.0.0.100',
256
 
                            'subnet_id': 'cccc'
257
 
                        }
258
 
                    ],
259
 
                    'id': 'dddd',
260
 
                    'mac_address': 'fa:16:3e:25:32:5d',
261
 
                    'name': 'test_stack.the_nic',
262
 
                    'network_id': 'aaaa',
263
 
                    'status': 'ACTIVE',
264
 
                    'tenant_id': 'c1210485b2424d48804aad5d39c61b8f'
265
 
                }
266
 
            })
 
517
                'name': self.nic_name,
 
518
                'admin_state_up': True}
 
519
        if security_groups:
 
520
                port['security_groups'] = security_groups
 
521
 
 
522
        quantumclient.Client.create_port({'port': port}).AndReturn({
 
523
            'port': {
 
524
                'admin_state_up': True,
 
525
                'device_id': '',
 
526
                'device_owner': '',
 
527
                'fixed_ips': [
 
528
                    {
 
529
                        'ip_address': '10.0.0.100',
 
530
                        'subnet_id': 'cccc'
 
531
                    }
 
532
                ],
 
533
                'id': 'dddd',
 
534
                'mac_address': 'fa:16:3e:25:32:5d',
 
535
                'name': self.nic_name,
 
536
                'network_id': 'aaaa',
 
537
                'status': 'ACTIVE',
 
538
                'tenant_id': 'c1210485b2424d48804aad5d39c61b8f'
 
539
            }
 
540
        })
267
541
 
268
542
    def mock_delete_network_interface(self):
269
543
        quantumclient.Client.delete_port('dddd').AndReturn(None)
270
544
 
271
545
    def test_network_interface(self):
 
546
        self.mock_create_security_group()
272
547
        self.mock_create_network()
273
548
        self.mock_create_subnet()
 
549
        self.mock_show_subnet()
274
550
        self.mock_create_network_interface()
275
551
        self.mock_delete_network_interface()
276
552
        self.mock_delete_subnet()
277
553
        self.mock_delete_network()
 
554
        self.mock_delete_security_group()
278
555
 
279
556
        self.m.ReplayAll()
280
557
 
281
558
        stack = self.create_stack(self.test_template)
282
 
        resource = stack['the_nic']
283
 
        self.assertResourceState(resource, 'dddd')
284
 
 
285
 
        self.assertEqual(resource.UPDATE_REPLACE, resource.handle_update({}))
286
 
 
 
559
        try:
 
560
            self.assertEqual((stack.CREATE, stack.COMPLETE), stack.state)
 
561
            rsrc = stack['the_nic']
 
562
            self.assertResourceState(rsrc, 'dddd')
 
563
 
 
564
            self.assertRaises(resource.UpdateReplace,
 
565
                              rsrc.handle_update, {}, {}, {})
 
566
 
 
567
        finally:
 
568
            stack.delete()
 
569
 
 
570
        self.m.VerifyAll()
 
571
 
 
572
    def test_network_interface_no_groupset(self):
 
573
        self.mock_create_network()
 
574
        self.mock_create_subnet()
 
575
        self.mock_show_subnet()
 
576
        self.mock_create_network_interface(security_groups=None)
 
577
        self.mock_delete_network_interface()
 
578
        self.mock_delete_subnet()
 
579
        self.mock_delete_network()
 
580
 
 
581
        self.m.ReplayAll()
 
582
 
 
583
        stack = self.create_stack(self.test_template_no_groupset)
287
584
        stack.delete()
288
 
        self.m.VerifyAll()
289
 
 
290
 
 
291
 
@attr(tag=['unit', 'resource'])
292
 
@attr(speed='fast')
 
585
 
 
586
        self.m.VerifyAll()
 
587
 
 
588
    def test_network_interface_error(self):
 
589
        real_exception = self.assertRaises(
 
590
            exception.InvalidTemplateReference,
 
591
            self.create_stack,
 
592
            self.test_template_error)
 
593
        expected_exception = exception.InvalidTemplateReference(
 
594
            resource='INVALID-REF-IN-TEMPLATE',
 
595
            key='GroupSet')
 
596
 
 
597
        self.assertEquals(str(expected_exception), str(real_exception))
 
598
 
 
599
    def test_network_interface_error_no_ref(self):
 
600
        self.mock_create_network()
 
601
        self.mock_create_subnet()
 
602
        self.mock_show_subnet()
 
603
        self.mock_delete_subnet()
 
604
        self.mock_delete_network()
 
605
 
 
606
        self.m.ReplayAll()
 
607
 
 
608
        stack = self.create_stack(self.test_template_error_no_ref)
 
609
        try:
 
610
            self.assertEqual((stack.CREATE, stack.FAILED), stack.state)
 
611
            rsrc = stack['the_nic']
 
612
            self.assertEqual((rsrc.CREATE, rsrc.FAILED), rsrc.state)
 
613
            reason = rsrc.status_reason
 
614
            self.assertTrue(reason.startswith('InvalidTemplateAttribute:'))
 
615
        finally:
 
616
            stack.delete()
 
617
 
 
618
        self.m.VerifyAll()
 
619
 
 
620
 
293
621
class InternetGatewayTest(VPCTestBase):
294
622
 
295
623
    test_template = '''
299
627
    Type: AWS::EC2::InternetGateway
300
628
  the_vpc:
301
629
    Type: AWS::EC2::VPC
302
 
    DependsOn : the_gateway
303
630
    Properties:
304
631
      CidrBlock: '10.0.0.0/16'
305
632
  the_subnet:
310
637
      AvailabilityZone: moon
311
638
  the_attachment:
312
639
    Type: AWS::EC2::VPCGatewayAttachment
313
 
    DependsOn : the_subnet
314
640
    Properties:
315
641
      VpcId: {Ref: the_vpc}
316
642
      InternetGatewayId: {Ref: the_gateway}
 
643
  the_route_table:
 
644
    Type: AWS::EC2::RouteTable
 
645
    Properties:
 
646
      VpcId: {Ref: the_vpc}
 
647
  the_association:
 
648
    Type: AWS::EC2::SubnetRouteTableAssocation
 
649
    Properties:
 
650
      RouteTableId: {Ref: the_route_table}
 
651
      SubnetId: {Ref: the_subnet}
317
652
'''
318
653
 
319
654
    def mock_create_internet_gateway(self):
331
666
 
332
667
    def mock_create_gateway_attachment(self):
333
668
        quantumclient.Client.add_gateway_router(
334
 
            'bbbb', {'network_id': 'eeee'}).AndReturn(None)
 
669
            'ffff', {'network_id': 'eeee'}).AndReturn(None)
335
670
 
336
671
    def mock_delete_gateway_attachment(self):
337
 
        quantumclient.Client.remove_gateway_router('bbbb').AndReturn(None)
 
672
        quantumclient.Client.remove_gateway_router('ffff').AndReturn(None)
338
673
 
339
674
    def test_internet_gateway(self):
340
675
        self.mock_create_internet_gateway()
341
676
        self.mock_create_network()
342
677
        self.mock_create_subnet()
 
678
        self.mock_create_route_table()
 
679
        self.mock_create_association()
343
680
        self.mock_create_gateway_attachment()
344
681
        self.mock_delete_gateway_attachment()
 
682
        self.mock_delete_association()
 
683
        self.mock_delete_route_table()
345
684
        self.mock_delete_subnet()
346
685
        self.mock_delete_network()
347
686
 
350
689
        stack = self.create_stack(self.test_template)
351
690
 
352
691
        gateway = stack['the_gateway']
353
 
        self.assertResourceState(gateway, 'the_gateway', {
354
 
            'external_network_id': 'eeee'})
355
 
        self.assertEqual(gateway.UPDATE_REPLACE, gateway.handle_update({}))
 
692
        self.assertResourceState(gateway, gateway.physical_resource_name())
 
693
        self.assertRaises(resource.UpdateReplace, gateway.handle_update,
 
694
                          {}, {}, {})
356
695
 
357
696
        attachment = stack['the_attachment']
358
697
        self.assertResourceState(attachment, 'the_attachment')
359
 
        self.assertEqual(gateway.UPDATE_REPLACE, attachment.handle_update({}))
 
698
        self.assertRaises(resource.UpdateReplace,
 
699
                          attachment.handle_update, {}, {}, {})
 
700
 
 
701
        route_table = stack['the_route_table']
 
702
        self.assertEqual([route_table], list(attachment._vpc_route_tables()))
360
703
 
361
704
        stack.delete()
362
705
        self.m.VerifyAll()
363
706
 
364
707
 
365
 
@attr(tag=['unit', 'resource'])
366
 
@attr(speed='fast')
367
708
class RouteTableTest(VPCTestBase):
368
709
 
369
710
    test_template = '''
390
731
      SubnetId: {Ref: the_subnet}
391
732
'''
392
733
 
393
 
    def mock_create_route_table(self):
394
 
        quantumclient.Client.create_router(
395
 
            {'router': {'name': u'test_stack.the_route_table'}}).AndReturn({
396
 
                'router': {
397
 
                    'status': 'ACTIVE',
398
 
                    'name': 'name',
399
 
                    'admin_state_up': True,
400
 
                    'tenant_id': 'c1210485b2424d48804aad5d39c61b8f',
401
 
                    'id': 'ffff'
402
 
                }
403
 
            })
404
 
 
405
 
    def mock_create_association(self):
406
 
        quantumclient.Client.remove_interface_router(
407
 
            'bbbb',
408
 
            {'subnet_id': u'cccc'}).AndReturn(None)
409
 
        quantumclient.Client.add_interface_router(
410
 
            u'ffff',
411
 
            {'subnet_id': 'cccc'}).AndReturn(None)
412
 
 
413
 
    def mock_delete_association(self):
414
 
        quantumclient.Client.remove_interface_router(
415
 
            'ffff',
416
 
            {'subnet_id': u'cccc'}).AndReturn(None)
417
 
        quantumclient.Client.add_interface_router(
418
 
            u'bbbb',
419
 
            {'subnet_id': 'cccc'}).AndReturn(None)
420
 
 
421
 
    def mock_delete_route_table(self):
422
 
        quantumclient.Client.delete_router('ffff').AndReturn(None)
423
 
 
424
734
    def test_route_table(self):
425
735
        self.mock_create_network()
426
736
        self.mock_create_subnet()
435
745
 
436
746
        stack = self.create_stack(self.test_template)
437
747
 
438
 
        vpc = stack['the_vpc']
439
 
        self.assertEqual(['bbbb', 'ffff'], vpc.metadata['all_router_ids'])
440
 
 
441
748
        route_table = stack['the_route_table']
442
 
        self.assertResourceState(route_table, 'ffff', {})
443
 
        self.assertEqual(
444
 
            route_table.UPDATE_REPLACE,
445
 
            route_table.handle_update({}))
 
749
        self.assertResourceState(route_table, 'ffff')
 
750
        self.assertRaises(
 
751
            resource.UpdateReplace,
 
752
            route_table.handle_update, {}, {}, {})
446
753
 
447
754
        association = stack['the_association']
448
 
        self.assertResourceState(association, 'the_association', {})
449
 
        self.assertEqual(
450
 
            association.UPDATE_REPLACE,
451
 
            association.handle_update({}))
 
755
        self.assertResourceState(association, 'the_association')
 
756
        self.assertRaises(
 
757
            resource.UpdateReplace,
 
758
            association.handle_update, {}, {}, {})
452
759
 
453
760
        association.delete()
454
761
        route_table.delete()
455
762
 
456
 
        vpc = stack['the_vpc']
457
 
        self.assertEqual(['bbbb'], vpc.metadata['all_router_ids'])
458
 
 
459
763
        stack.delete()
460
764
        self.m.VerifyAll()