~openstack-charmers-archive/charms/trusty/neutron-gateway/trunk

« back to all changes in this revision

Viewing changes to tests/basic_deployment.py

  • Committer: James Page
  • Date: 2015-10-22 13:23:58 UTC
  • Revision ID: james.page@ubuntu.com-20151022132358-qin1nvlnqn4aezaz
Tags: 15.10
15.10 Charm release

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
#!/usr/bin/python
2
 
 
3
1
import amulet
4
2
import os
5
3
import time
13
11
 
14
12
from charmhelpers.contrib.openstack.amulet.utils import (
15
13
    OpenStackAmuletUtils,
16
 
    DEBUG, # flake8: noqa
17
 
    ERROR
 
14
    DEBUG,
 
15
    # ERROR
18
16
)
19
17
 
20
18
# Use DEBUG to turn on debug logging
25
23
    """Amulet tests on a basic neutron-gateway deployment."""
26
24
 
27
25
    def __init__(self, series, openstack=None, source=None, git=False,
28
 
                 stable=True):
 
26
                 stable=False):
29
27
        """Deploy the entire test environment."""
30
28
        super(NeutronGatewayBasicDeployment, self).__init__(series, openstack,
31
29
                                                            source, stable)
45
43
           """
46
44
        this_service = {'name': 'neutron-gateway'}
47
45
        other_services = [{'name': 'mysql'},
48
 
                          {'name': 'rabbitmq-server'}, {'name': 'keystone'},
49
 
                          {'name': 'nova-cloud-controller'}]
50
 
        if self._get_openstack_release() >= self.trusty_kilo:
51
 
            other_services.append({'name': 'neutron-api'})
52
 
        super(NeutronGatewayBasicDeployment, self)._add_services(this_service,
53
 
                                                                 other_services)
 
46
                          {'name': 'rabbitmq-server'},
 
47
                          {'name': 'keystone'},
 
48
                          {'name': 'glance'},  # satisfy workload status
 
49
                          {'name': 'nova-cloud-controller'},
 
50
                          {'name': 'nova-compute'},  # satisfy workload stat
 
51
                          {'name': 'neutron-api'}]
 
52
 
 
53
        super(NeutronGatewayBasicDeployment, self)._add_services(
 
54
            this_service, other_services)
54
55
 
55
56
    def _add_relations(self):
56
57
        """Add all of the relations for the services."""
57
58
        relations = {
58
 
          'keystone:shared-db': 'mysql:shared-db',
59
 
          'neutron-gateway:shared-db': 'mysql:shared-db',
60
 
          'neutron-gateway:amqp': 'rabbitmq-server:amqp',
61
 
          'nova-cloud-controller:quantum-network-service': \
62
 
                                      'neutron-gateway:quantum-network-service',
63
 
          'nova-cloud-controller:shared-db': 'mysql:shared-db',
64
 
          'nova-cloud-controller:identity-service': 'keystone:identity-service',
65
 
          'nova-cloud-controller:amqp': 'rabbitmq-server:amqp'
 
59
            'keystone:shared-db': 'mysql:shared-db',
 
60
            'neutron-gateway:shared-db': 'mysql:shared-db',
 
61
            'neutron-gateway:amqp': 'rabbitmq-server:amqp',
 
62
            'nova-cloud-controller:quantum-network-service':
 
63
            'neutron-gateway:quantum-network-service',
 
64
            'nova-cloud-controller:shared-db': 'mysql:shared-db',
 
65
            'nova-cloud-controller:identity-service': 'keystone:'
 
66
                                                      'identity-service',
 
67
            'nova-cloud-controller:amqp': 'rabbitmq-server:amqp',
 
68
            'neutron-api:shared-db': 'mysql:shared-db',
 
69
            'neutron-api:amqp': 'rabbitmq-server:amqp',
 
70
            'neutron-api:neutron-api': 'nova-cloud-controller:neutron-api',
 
71
            'neutron-api:identity-service': 'keystone:identity-service',
 
72
            'glance:identity-service': 'keystone:identity-service',
 
73
            'glance:shared-db': 'mysql:shared-db',
 
74
            'glance:amqp': 'rabbitmq-server:amqp',
 
75
            'nova-cloud-controller:cloud-compute': 'nova-compute:'
 
76
                                                   'cloud-compute',
 
77
            'nova-compute:amqp': 'rabbitmq-server:amqp',
 
78
            'nova-compute:image-service': 'glance:image-service',
 
79
            'nova-cloud-controller:image-service': 'glance:image-service',
66
80
        }
67
 
        if self._get_openstack_release() >= self.trusty_kilo:
68
 
            relations['neutron-api:shared-db'] = 'mysql:shared-db'
69
 
            relations['neutron-api:amqp'] = 'rabbitmq-server:amqp'
70
 
            relations['neutron-api:neutron-api'] = 'nova-cloud-controller:neutron-api'
71
 
            relations['neutron-api:identity-service'] = 'keystone:identity-service'
72
81
        super(NeutronGatewayBasicDeployment, self)._add_relations(relations)
73
82
 
74
83
    def _configure_services(self):
83
92
                openstack_origin_git = {
84
93
                    'repositories': [
85
94
                        {'name': 'requirements',
86
 
                         'repository': 'git://github.com/openstack/requirements',
 
95
                         'repository': 'git://github.com/openstack/requirements',  # noqa
87
96
                         'branch': branch},
88
97
                        {'name': 'neutron-fwaas',
89
 
                         'repository': 'git://github.com/openstack/neutron-fwaas',
 
98
                         'repository': 'git://github.com/openstack/neutron-fwaas',  # noqa
90
99
                         'branch': branch},
91
100
                        {'name': 'neutron-lbaas',
92
 
                         'repository': 'git://github.com/openstack/neutron-lbaas',
 
101
                         'repository': 'git://github.com/openstack/neutron-lbaas',  # noqa
93
102
                         'branch': branch},
94
103
                        {'name': 'neutron-vpnaas',
95
 
                         'repository': 'git://github.com/openstack/neutron-vpnaas',
 
104
                         'repository': 'git://github.com/openstack/neutron-vpnaas',  # noqa
96
105
                         'branch': branch},
97
106
                        {'name': 'neutron',
98
107
                         'repository': 'git://github.com/openstack/neutron',
122
131
                    'http_proxy': amulet_http_proxy,
123
132
                    'https_proxy': amulet_http_proxy,
124
133
                }
125
 
            neutron_gateway_config['openstack-origin-git'] = yaml.dump(openstack_origin_git)
 
134
 
 
135
            neutron_gateway_config['openstack-origin-git'] = \
 
136
                yaml.dump(openstack_origin_git)
 
137
 
126
138
        keystone_config = {'admin-password': 'openstack',
127
139
                           'admin-token': 'ubuntutesting'}
128
140
        nova_cc_config = {'network-manager': 'Quantum',
137
149
        # Access the sentries for inspecting service units
138
150
        self.mysql_sentry = self.d.sentry.unit['mysql/0']
139
151
        self.keystone_sentry = self.d.sentry.unit['keystone/0']
140
 
        self.rabbitmq_sentry = self.d.sentry.unit['rabbitmq-server/0']
 
152
        self.rmq_sentry = self.d.sentry.unit['rabbitmq-server/0']
141
153
        self.nova_cc_sentry = self.d.sentry.unit['nova-cloud-controller/0']
142
154
        self.neutron_gateway_sentry = self.d.sentry.unit['neutron-gateway/0']
 
155
        self.neutron_api_sentry = self.d.sentry.unit['neutron-api/0']
143
156
 
144
157
        # Let things settle a bit before moving forward
145
158
        time.sleep(30)
150
163
                                                      password='openstack',
151
164
                                                      tenant='admin')
152
165
 
153
 
 
154
166
        # Authenticate admin with neutron
155
167
        ep = self.keystone.service_catalog.url_for(service_type='identity',
156
168
                                                   endpoint_type='publicURL')
160
172
                                            tenant_name='admin',
161
173
                                            region_name='RegionOne')
162
174
 
163
 
    def test_services(self):
 
175
    def test_100_services(self):
164
176
        """Verify the expected services are running on the corresponding
165
177
           service units."""
166
 
        neutron_services = ['status neutron-dhcp-agent',
167
 
                            'status neutron-lbaas-agent',
168
 
                            'status neutron-metadata-agent',
169
 
                            'status neutron-metering-agent',
170
 
                            'status neutron-ovs-cleanup',
171
 
                            'status neutron-plugin-openvswitch-agent']
 
178
        neutron_services = ['neutron-dhcp-agent',
 
179
                            'neutron-lbaas-agent',
 
180
                            'neutron-metadata-agent',
 
181
                            'neutron-metering-agent',
 
182
                            'neutron-ovs-cleanup',
 
183
                            'neutron-plugin-openvswitch-agent']
172
184
 
173
185
        if self._get_openstack_release() <= self.trusty_juno:
174
 
            neutron_services.append('status neutron-vpn-agent')
 
186
            neutron_services.append('neutron-vpn-agent')
175
187
 
176
 
        nova_cc_services = ['status nova-api-ec2',
177
 
                            'status nova-api-os-compute',
178
 
                            'status nova-objectstore',
179
 
                            'status nova-cert',
180
 
                            'status nova-scheduler']
181
 
        if self._get_openstack_release() >= self.precise_grizzly:
182
 
            nova_cc_services.append('status nova-conductor')
 
188
        nova_cc_services = ['nova-api-ec2',
 
189
                            'nova-api-os-compute',
 
190
                            'nova-objectstore',
 
191
                            'nova-cert',
 
192
                            'nova-scheduler',
 
193
                            'nova-conductor']
183
194
 
184
195
        commands = {
185
 
            self.mysql_sentry: ['status mysql'],
186
 
            self.keystone_sentry: ['status keystone'],
 
196
            self.mysql_sentry: ['mysql'],
 
197
            self.keystone_sentry: ['keystone'],
187
198
            self.nova_cc_sentry: nova_cc_services,
188
199
            self.neutron_gateway_sentry: neutron_services
189
200
        }
190
201
 
191
 
        ret = u.validate_services(commands)
192
 
        if ret:
193
 
            amulet.raise_status(amulet.FAIL, msg=ret)
194
 
 
195
 
    def test_neutron_gateway_shared_db_relation(self):
 
202
        ret = u.validate_services_by_name(commands)
 
203
        if ret:
 
204
            amulet.raise_status(amulet.FAIL, msg=ret)
 
205
 
 
206
    def test_102_service_catalog(self):
 
207
        """Verify that the service catalog endpoint data is valid."""
 
208
        u.log.debug('Checking keystone service catalog...')
 
209
        endpoint_check = {
 
210
            'adminURL': u.valid_url,
 
211
            'id': u.not_null,
 
212
            'region': 'RegionOne',
 
213
            'publicURL': u.valid_url,
 
214
            'internalURL': u.valid_url
 
215
        }
 
216
        expected = {
 
217
            'network': [endpoint_check],
 
218
            'compute': [endpoint_check],
 
219
            'identity': [endpoint_check]
 
220
        }
 
221
        actual = self.keystone.service_catalog.get_endpoints()
 
222
 
 
223
        ret = u.validate_svc_catalog_endpoint_data(expected, actual)
 
224
        if ret:
 
225
            amulet.raise_status(amulet.FAIL, msg=ret)
 
226
 
 
227
    def test_104_network_endpoint(self):
 
228
        """Verify the neutron network endpoint data."""
 
229
        u.log.debug('Checking neutron network api endpoint data...')
 
230
        endpoints = self.keystone.endpoints.list()
 
231
        admin_port = internal_port = public_port = '9696'
 
232
        expected = {
 
233
            'id': u.not_null,
 
234
            'region': 'RegionOne',
 
235
            'adminurl': u.valid_url,
 
236
            'internalurl': u.valid_url,
 
237
            'publicurl': u.valid_url,
 
238
            'service_id': u.not_null
 
239
        }
 
240
        ret = u.validate_endpoint_data(endpoints, admin_port, internal_port,
 
241
                                       public_port, expected)
 
242
 
 
243
        if ret:
 
244
            amulet.raise_status(amulet.FAIL,
 
245
                                msg='glance endpoint: {}'.format(ret))
 
246
 
 
247
    def test_110_users(self):
 
248
        """Verify expected users."""
 
249
        u.log.debug('Checking keystone users...')
 
250
        expected = [
 
251
            {'name': 'admin',
 
252
             'enabled': True,
 
253
             'tenantId': u.not_null,
 
254
             'id': u.not_null,
 
255
             'email': 'juju@localhost'},
 
256
            {'name': 'quantum',
 
257
             'enabled': True,
 
258
             'tenantId': u.not_null,
 
259
             'id': u.not_null,
 
260
             'email': 'juju@localhost'}
 
261
        ]
 
262
 
 
263
        if self._get_openstack_release() >= self.trusty_kilo:
 
264
            # Kilo or later
 
265
            expected.append({
 
266
                'name': 'nova',
 
267
                'enabled': True,
 
268
                'tenantId': u.not_null,
 
269
                'id': u.not_null,
 
270
                'email': 'juju@localhost'
 
271
            })
 
272
        else:
 
273
            # Juno and earlier
 
274
            expected.append({
 
275
                'name': 's3_ec2_nova',
 
276
                'enabled': True,
 
277
                'tenantId': u.not_null,
 
278
                'id': u.not_null,
 
279
                'email': 'juju@localhost'
 
280
            })
 
281
 
 
282
        actual = self.keystone.users.list()
 
283
        ret = u.validate_user_data(expected, actual)
 
284
        if ret:
 
285
            amulet.raise_status(amulet.FAIL, msg=ret)
 
286
 
 
287
    def test_200_neutron_gateway_mysql_shared_db_relation(self):
196
288
        """Verify the neutron-gateway to mysql shared-db relation data"""
 
289
        u.log.debug('Checking neutron-gateway:mysql db relation data...')
197
290
        unit = self.neutron_gateway_sentry
198
291
        relation = ['shared-db', 'mysql:shared-db']
199
292
        expected = {
208
301
            message = u.relation_error('neutron-gateway shared-db', ret)
209
302
            amulet.raise_status(amulet.FAIL, msg=message)
210
303
 
211
 
    def test_mysql_shared_db_relation(self):
 
304
    def test_201_mysql_neutron_gateway_shared_db_relation(self):
212
305
        """Verify the mysql to neutron-gateway shared-db relation data"""
 
306
        u.log.debug('Checking mysql:neutron-gateway db relation data...')
213
307
        unit = self.mysql_sentry
214
308
        relation = ['shared-db', 'neutron-gateway:shared-db']
215
309
        expected = {
223
317
            message = u.relation_error('mysql shared-db', ret)
224
318
            amulet.raise_status(amulet.FAIL, msg=message)
225
319
 
226
 
    def test_neutron_gateway_amqp_relation(self):
 
320
    def test_202_neutron_gateway_rabbitmq_amqp_relation(self):
227
321
        """Verify the neutron-gateway to rabbitmq-server amqp relation data"""
 
322
        u.log.debug('Checking neutron-gateway:rmq amqp relation data...')
228
323
        unit = self.neutron_gateway_sentry
229
324
        relation = ['amqp', 'rabbitmq-server:amqp']
230
325
        expected = {
238
333
            message = u.relation_error('neutron-gateway amqp', ret)
239
334
            amulet.raise_status(amulet.FAIL, msg=message)
240
335
 
241
 
    def test_rabbitmq_amqp_relation(self):
 
336
    def test_203_rabbitmq_neutron_gateway_amqp_relation(self):
242
337
        """Verify the rabbitmq-server to neutron-gateway amqp relation data"""
243
 
        unit = self.rabbitmq_sentry
 
338
        u.log.debug('Checking rmq:neutron-gateway amqp relation data...')
 
339
        unit = self.rmq_sentry
244
340
        relation = ['amqp', 'neutron-gateway:amqp']
245
341
        expected = {
246
342
            'private-address': u.valid_ip,
253
349
            message = u.relation_error('rabbitmq amqp', ret)
254
350
            amulet.raise_status(amulet.FAIL, msg=message)
255
351
 
256
 
    def test_neutron_gateway_network_service_relation(self):
 
352
    def test_204_neutron_gateway_network_service_relation(self):
257
353
        """Verify the neutron-gateway to nova-cc quantum-network-service
258
354
           relation data"""
 
355
        u.log.debug('Checking neutron-gateway:nova-cc net svc '
 
356
                    'relation data...')
259
357
        unit = self.neutron_gateway_sentry
260
358
        relation = ['quantum-network-service',
261
359
                    'nova-cloud-controller:quantum-network-service']
268
366
            message = u.relation_error('neutron-gateway network-service', ret)
269
367
            amulet.raise_status(amulet.FAIL, msg=message)
270
368
 
271
 
    def test_nova_cc_network_service_relation(self):
 
369
    def test_205_nova_cc_network_service_relation(self):
272
370
        """Verify the nova-cc to neutron-gateway quantum-network-service
273
371
           relation data"""
 
372
        u.log.debug('Checking nova-cc:neutron-gateway net svc '
 
373
                    'relation data...')
274
374
        unit = self.nova_cc_sentry
275
375
        relation = ['quantum-network-service',
276
376
                    'neutron-gateway:quantum-network-service']
289
389
            'keystone_host': u.valid_ip,
290
390
            'quantum_plugin': 'ovs',
291
391
            'auth_host': u.valid_ip,
292
 
            'service_username': 'quantum_s3_ec2_nova',
293
392
            'service_tenant_name': 'services'
294
393
        }
 
394
 
295
395
        if self._get_openstack_release() >= self.trusty_kilo:
 
396
            # Kilo or later
296
397
            expected['service_username'] = 'nova'
 
398
        else:
 
399
            # Juno or earlier
 
400
            expected['service_username'] = 's3_ec2_nova'
297
401
 
298
402
        ret = u.validate_relation_data(unit, relation, expected)
299
403
        if ret:
300
404
            message = u.relation_error('nova-cc network-service', ret)
301
405
            amulet.raise_status(amulet.FAIL, msg=message)
302
406
 
303
 
    def test_z_restart_on_config_change(self):
304
 
        """Verify that the specified services are restarted when the config
305
 
           is changed.
306
 
 
307
 
           Note(coreycb): The method name with the _z_ is a little odd
308
 
           but it forces the test to run last.  It just makes things
309
 
           easier because restarting services requires re-authorization.
310
 
           """
311
 
        conf = '/etc/neutron/neutron.conf'
312
 
 
313
 
        services = ['neutron-dhcp-agent',
314
 
                    'neutron-lbaas-agent',
315
 
                    'neutron-metadata-agent',
316
 
                    'neutron-metering-agent',
317
 
                    'neutron-openvswitch-agent']
318
 
 
319
 
        if self._get_openstack_release() <= self.trusty_juno:
320
 
            services.append('neutron-vpn-agent')
321
 
 
322
 
        u.log.debug("Making config change on neutron-gateway...")
323
 
        self.d.configure('neutron-gateway', {'debug': 'True'})
324
 
 
325
 
        time = 60
326
 
        for s in services:
327
 
            u.log.debug("Checking that service restarted: {}".format(s))
328
 
            if not u.service_restarted(self.neutron_gateway_sentry, s, conf,
329
 
                                       pgrep_full=True, sleep_time=time):
330
 
                self.d.configure('neutron-gateway', {'debug': 'False'})
331
 
                msg = "service {} didn't restart after config change".format(s)
332
 
                amulet.raise_status(amulet.FAIL, msg=msg)
333
 
            time = 0
334
 
 
335
 
        self.d.configure('neutron-gateway', {'debug': 'False'})
336
 
 
337
 
    def test_neutron_config(self):
 
407
    def test_206_neutron_api_shared_db_relation(self):
 
408
        """Verify the neutron-api to mysql shared-db relation data"""
 
409
        u.log.debug('Checking neutron-api:mysql db relation data...')
 
410
        unit = self.neutron_api_sentry
 
411
        relation = ['shared-db', 'mysql:shared-db']
 
412
        expected = {
 
413
            'private-address': u.valid_ip,
 
414
            'database': 'neutron',
 
415
            'username': 'neutron',
 
416
            'hostname': u.valid_ip
 
417
        }
 
418
 
 
419
        ret = u.validate_relation_data(unit, relation, expected)
 
420
        if ret:
 
421
            message = u.relation_error('neutron-api shared-db', ret)
 
422
            amulet.raise_status(amulet.FAIL, msg=message)
 
423
 
 
424
    def test_207_shared_db_neutron_api_relation(self):
 
425
        """Verify the mysql to neutron-api shared-db relation data"""
 
426
        u.log.debug('Checking mysql:neutron-api db relation data...')
 
427
        unit = self.mysql_sentry
 
428
        relation = ['shared-db', 'neutron-api:shared-db']
 
429
        expected = {
 
430
            'db_host': u.valid_ip,
 
431
            'private-address': u.valid_ip,
 
432
            'password': u.not_null,
 
433
            'allowed_units': u.not_null,
 
434
        }
 
435
 
 
436
        ret = u.validate_relation_data(unit, relation, expected)
 
437
        if ret:
 
438
            message = u.relation_error('mysql shared-db', ret)
 
439
            amulet.raise_status(amulet.FAIL, msg=message)
 
440
        relation_data = unit.relation(relation[0], relation[1])
 
441
        allowed_units = relation_data['allowed_units'].split()
 
442
        if 'neutron-api/0' not in allowed_units:
 
443
            message = 'neutron-api/0 not found in allowed_units'
 
444
            amulet.raise_status(amulet.FAIL, msg=message)
 
445
 
 
446
    def test_208_neutron_api_amqp_relation(self):
 
447
        """Verify the neutron-api to rabbitmq-server amqp relation data"""
 
448
        u.log.debug('Checking neutron-api:amqp relation data...')
 
449
        unit = self.neutron_api_sentry
 
450
        relation = ['amqp', 'rabbitmq-server:amqp']
 
451
        expected = {
 
452
            'username': 'neutron',
 
453
            'private-address': u.valid_ip,
 
454
            'vhost': 'openstack'
 
455
        }
 
456
 
 
457
        ret = u.validate_relation_data(unit, relation, expected)
 
458
        if ret:
 
459
            message = u.relation_error('neutron-api amqp', ret)
 
460
            amulet.raise_status(amulet.FAIL, msg=message)
 
461
 
 
462
    def test_209_amqp_neutron_api_relation(self):
 
463
        """Verify the rabbitmq-server to neutron-api amqp relation data"""
 
464
        u.log.debug('Checking amqp:neutron-api relation data...')
 
465
        unit = self.rmq_sentry
 
466
        relation = ['amqp', 'neutron-api:amqp']
 
467
        expected = {
 
468
            'hostname': u.valid_ip,
 
469
            'private-address': u.valid_ip,
 
470
            'password': u.not_null
 
471
        }
 
472
 
 
473
        ret = u.validate_relation_data(unit, relation, expected)
 
474
        if ret:
 
475
            message = u.relation_error('rabbitmq amqp', ret)
 
476
            amulet.raise_status(amulet.FAIL, msg=message)
 
477
 
 
478
    def test_210_neutron_api_keystone_identity_relation(self):
 
479
        """Verify the neutron-api to keystone identity-service relation data"""
 
480
        u.log.debug('Checking neutron-api:keystone id relation data...')
 
481
        unit = self.neutron_api_sentry
 
482
        relation = ['identity-service', 'keystone:identity-service']
 
483
        api_ip = unit.relation('identity-service',
 
484
                               'keystone:identity-service')['private-address']
 
485
        api_endpoint = 'http://{}:9696'.format(api_ip)
 
486
        expected = {
 
487
            'private-address': u.valid_ip,
 
488
            'quantum_region': 'RegionOne',
 
489
            'quantum_service': 'quantum',
 
490
            'quantum_admin_url': api_endpoint,
 
491
            'quantum_internal_url': api_endpoint,
 
492
            'quantum_public_url': api_endpoint,
 
493
        }
 
494
 
 
495
        ret = u.validate_relation_data(unit, relation, expected)
 
496
        if ret:
 
497
            message = u.relation_error('neutron-api identity-service', ret)
 
498
            amulet.raise_status(amulet.FAIL, msg=message)
 
499
 
 
500
    def test_211_keystone_neutron_api_identity_relation(self):
 
501
        """Verify the keystone to neutron-api identity-service relation data"""
 
502
        u.log.debug('Checking keystone:neutron-api id relation data...')
 
503
        unit = self.keystone_sentry
 
504
        relation = ['identity-service', 'neutron-api:identity-service']
 
505
        rel_ks_id = unit.relation('identity-service',
 
506
                                  'neutron-api:identity-service')
 
507
        id_ip = rel_ks_id['private-address']
 
508
        expected = {
 
509
            'admin_token': 'ubuntutesting',
 
510
            'auth_host': id_ip,
 
511
            'auth_port': "35357",
 
512
            'auth_protocol': 'http',
 
513
            'private-address': id_ip,
 
514
            'service_host': id_ip,
 
515
        }
 
516
        ret = u.validate_relation_data(unit, relation, expected)
 
517
        if ret:
 
518
            message = u.relation_error('neutron-api identity-service', ret)
 
519
            amulet.raise_status(amulet.FAIL, msg=message)
 
520
 
 
521
    def test_212_neutron_api_novacc_relation(self):
 
522
        """Verify the neutron-api to nova-cloud-controller relation data"""
 
523
        u.log.debug('Checking neutron-api:novacc relation data...')
 
524
        unit = self.neutron_api_sentry
 
525
        relation = ['neutron-api', 'nova-cloud-controller:neutron-api']
 
526
        api_ip = unit.relation('identity-service',
 
527
                               'keystone:identity-service')['private-address']
 
528
        api_endpoint = 'http://{}:9696'.format(api_ip)
 
529
        expected = {
 
530
            'private-address': api_ip,
 
531
            'neutron-plugin': 'ovs',
 
532
            'neutron-security-groups': "no",
 
533
            'neutron-url': api_endpoint,
 
534
        }
 
535
        ret = u.validate_relation_data(unit, relation, expected)
 
536
        if ret:
 
537
            message = u.relation_error('neutron-api neutron-api', ret)
 
538
            amulet.raise_status(amulet.FAIL, msg=message)
 
539
 
 
540
    def test_213_novacc_neutron_api_relation(self):
 
541
        """Verify the nova-cloud-controller to neutron-api relation data"""
 
542
        u.log.debug('Checking novacc:neutron-api relation data...')
 
543
        unit = self.nova_cc_sentry
 
544
        relation = ['neutron-api', 'neutron-api:neutron-api']
 
545
        cc_ip = unit.relation('neutron-api',
 
546
                              'neutron-api:neutron-api')['private-address']
 
547
        cc_endpoint = 'http://{}:8774/v2'.format(cc_ip)
 
548
        expected = {
 
549
            'private-address': cc_ip,
 
550
            'nova_url': cc_endpoint,
 
551
        }
 
552
        ret = u.validate_relation_data(unit, relation, expected)
 
553
        if ret:
 
554
            message = u.relation_error('nova-cc neutron-api', ret)
 
555
            amulet.raise_status(amulet.FAIL, msg=message)
 
556
 
 
557
    def test_300_neutron_config(self):
338
558
        """Verify the data in the neutron config file."""
 
559
        u.log.debug('Checking neutron gateway config file data...')
339
560
        unit = self.neutron_gateway_sentry
340
 
        rabbitmq_relation = self.rabbitmq_sentry.relation('amqp',
341
 
                                                         'neutron-gateway:amqp')
 
561
        rmq_ng_rel = self.rmq_sentry.relation(
 
562
            'amqp', 'neutron-gateway:amqp')
342
563
 
343
564
        conf = '/etc/neutron/neutron.conf'
344
565
        expected = {
350
571
                'notification_driver': 'neutron.openstack.common.notifier.'
351
572
                                       'list_notifier',
352
573
                'list_notifier_drivers': 'neutron.openstack.common.'
353
 
                                         'notifier.rabbit_notifier'
 
574
                                         'notifier.rabbit_notifier',
354
575
            },
355
576
            'agent': {
356
577
                'root_helper': 'sudo /usr/bin/neutron-rootwrap '
357
578
                               '/etc/neutron/rootwrap.conf'
358
579
            }
359
580
        }
 
581
 
360
582
        if self._get_openstack_release() >= self.trusty_kilo:
361
 
            oslo_concurrency = {
362
 
                'oslo_concurrency': {
363
 
                    'lock_path':'/var/lock/neutron'
364
 
                }
365
 
            }
366
 
            oslo_messaging_rabbit = {
367
 
                'oslo_messaging_rabbit': {
368
 
                    'rabbit_userid': 'neutron',
369
 
                    'rabbit_virtual_host': 'openstack',
370
 
                    'rabbit_password': rabbitmq_relation['password'],
371
 
                    'rabbit_host': rabbitmq_relation['hostname'],
372
 
                }
373
 
            }
374
 
            expected.update(oslo_concurrency)
375
 
            expected.update(oslo_messaging_rabbit)
 
583
            # Kilo or later
 
584
            expected['oslo_messaging_rabbit'] = {
 
585
                'rabbit_userid': 'neutron',
 
586
                'rabbit_virtual_host': 'openstack',
 
587
                'rabbit_password': rmq_ng_rel['password'],
 
588
                'rabbit_host': rmq_ng_rel['hostname'],
 
589
            }
 
590
            expected['oslo_concurrency'] = {
 
591
                'lock_path': '/var/lock/neutron'
 
592
            }
376
593
        else:
377
 
            expected['DEFAULT']['lock_path'] = '/var/lock/neutron'
378
 
            expected['DEFAULT']['rabbit_userid'] = 'neutron'
379
 
            expected['DEFAULT']['rabbit_virtual_host'] = 'openstack'
380
 
            expected['DEFAULT']['rabbit_password'] = rabbitmq_relation['password']
381
 
            expected['DEFAULT']['rabbit_host'] = rabbitmq_relation['hostname']
 
594
            # Juno or earlier
 
595
            expected['DEFAULT'].update({
 
596
                'rabbit_userid': 'neutron',
 
597
                'rabbit_virtual_host': 'openstack',
 
598
                'rabbit_password': rmq_ng_rel['password'],
 
599
                'rabbit_host': rmq_ng_rel['hostname'],
 
600
                'lock_path': '/var/lock/neutron',
 
601
            })
382
602
 
383
603
        for section, pairs in expected.iteritems():
384
604
            ret = u.validate_config_data(unit, conf, section, pairs)
386
606
                message = "neutron config error: {}".format(ret)
387
607
                amulet.raise_status(amulet.FAIL, msg=message)
388
608
 
389
 
    def test_ml2_config(self):
 
609
    def test_301_neutron_ml2_config(self):
390
610
        """Verify the data in the ml2 config file. This is only available
391
611
           since icehouse."""
 
612
        u.log.debug('Checking neutron gateway ml2 config file data...')
392
613
        if self._get_openstack_release() < self.precise_icehouse:
393
614
            return
394
615
 
395
616
        unit = self.neutron_gateway_sentry
396
617
        conf = '/etc/neutron/plugins/ml2/ml2_conf.ini'
397
 
        neutron_gateway_relation = unit.relation('shared-db', 'mysql:shared-db')
 
618
        ng_db_rel = unit.relation('shared-db', 'mysql:shared-db')
 
619
 
398
620
        expected = {
399
621
            'ml2': {
400
622
                'type_drivers': 'gre,vxlan,vlan,flat',
401
623
                'tenant_network_types': 'gre,vxlan,vlan,flat',
402
 
                'mechanism_drivers': 'openvswitch,l2population'
 
624
                'mechanism_drivers': 'openvswitch,hyperv,l2population'
403
625
            },
404
626
            'ml2_type_gre': {
405
627
                'tunnel_id_ranges': '1:1000'
409
631
            },
410
632
            'ovs': {
411
633
                'enable_tunneling': 'True',
412
 
                'local_ip': neutron_gateway_relation['private-address']
 
634
                'local_ip': ng_db_rel['private-address']
413
635
            },
414
636
            'agent': {
415
637
                'tunnel_types': 'gre',
427
649
                message = "ml2 config error: {}".format(ret)
428
650
                amulet.raise_status(amulet.FAIL, msg=message)
429
651
 
430
 
    def test_dhcp_agent_config(self):
 
652
    def test_302_neutron_dhcp_agent_config(self):
431
653
        """Verify the data in the dhcp agent config file."""
 
654
        u.log.debug('Checking neutron gateway dhcp agent config file data...')
432
655
        unit = self.neutron_gateway_sentry
433
656
        conf = '/etc/neutron/dhcp_agent.ini'
434
657
        expected = {
440
663
                           '/etc/neutron/rootwrap.conf',
441
664
            'ovs_use_veth': 'True'
442
665
        }
 
666
        section = 'DEFAULT'
443
667
 
444
 
        ret = u.validate_config_data(unit, conf, 'DEFAULT', expected)
 
668
        ret = u.validate_config_data(unit, conf, section, expected)
445
669
        if ret:
446
670
            message = "dhcp agent config error: {}".format(ret)
447
671
            amulet.raise_status(amulet.FAIL, msg=message)
448
672
 
449
 
    def test_fwaas_driver_config(self):
 
673
    def test_303_neutron_fwaas_driver_config(self):
450
674
        """Verify the data in the fwaas driver config file.  This is only
451
675
           available since havana."""
452
 
        if self._get_openstack_release() < self.precise_havana:
453
 
            return
454
 
 
 
676
        u.log.debug('Checking neutron gateway fwaas config file data...')
455
677
        unit = self.neutron_gateway_sentry
456
678
        conf = '/etc/neutron/fwaas_driver.ini'
 
679
        expected = {
 
680
            'enabled': 'True'
 
681
        }
 
682
        section = 'fwaas'
 
683
 
457
684
        if self._get_openstack_release() >= self.trusty_kilo:
458
 
            expected = {
459
 
                'driver': 'neutron_fwaas.services.firewall.drivers.'
460
 
                          'linux.iptables_fwaas.IptablesFwaasDriver',
461
 
                'enabled': 'True'
462
 
            }
 
685
            # Kilo or later
 
686
            expected['driver'] = ('neutron_fwaas.services.firewall.drivers.'
 
687
                                  'linux.iptables_fwaas.IptablesFwaasDriver')
463
688
        else:
464
 
            expected = {
465
 
                'driver': 'neutron.services.firewall.drivers.'
466
 
                          'linux.iptables_fwaas.IptablesFwaasDriver',
467
 
                'enabled': 'True'
468
 
            }
 
689
            # Juno or earlier
 
690
            expected['driver'] = ('neutron.services.firewall.drivers.linux.'
 
691
                                  'iptables_fwaas.IptablesFwaasDriver')
469
692
 
470
 
        ret = u.validate_config_data(unit, conf, 'fwaas', expected)
 
693
        ret = u.validate_config_data(unit, conf, section, expected)
471
694
        if ret:
472
695
            message = "fwaas driver config error: {}".format(ret)
473
696
            amulet.raise_status(amulet.FAIL, msg=message)
474
697
 
475
 
    def test_l3_agent_config(self):
 
698
    def test_304_neutron_l3_agent_config(self):
476
699
        """Verify the data in the l3 agent config file."""
 
700
        u.log.debug('Checking neutron gateway l3 agent config file data...')
477
701
        unit = self.neutron_gateway_sentry
478
 
        nova_cc_relation = self.nova_cc_sentry.relation(\
479
 
                                      'quantum-network-service',
480
 
                                      'neutron-gateway:quantum-network-service')
 
702
        ncc_ng_rel = self.nova_cc_sentry.relation(
 
703
            'quantum-network-service',
 
704
            'neutron-gateway:quantum-network-service')
481
705
        ep = self.keystone.service_catalog.url_for(service_type='identity',
482
706
                                                   endpoint_type='publicURL')
483
707
 
488
712
            'auth_url': ep,
489
713
            'auth_region': 'RegionOne',
490
714
            'admin_tenant_name': 'services',
491
 
            'admin_user': 'quantum_s3_ec2_nova',
492
 
            'admin_password': nova_cc_relation['service_password'],
 
715
            'admin_password': ncc_ng_rel['service_password'],
493
716
            'root_helper': 'sudo /usr/bin/neutron-rootwrap '
494
717
                           '/etc/neutron/rootwrap.conf',
495
718
            'ovs_use_veth': 'True',
496
719
            'handle_internal_only_routers': 'True'
497
720
        }
 
721
        section = 'DEFAULT'
 
722
 
498
723
        if self._get_openstack_release() >= self.trusty_kilo:
 
724
            # Kilo or later
499
725
            expected['admin_user'] = 'nova'
 
726
        else:
 
727
            # Juno or earlier
 
728
            expected['admin_user'] = 's3_ec2_nova'
500
729
 
501
 
        ret = u.validate_config_data(unit, conf, 'DEFAULT', expected)
 
730
        ret = u.validate_config_data(unit, conf, section, expected)
502
731
        if ret:
503
732
            message = "l3 agent config error: {}".format(ret)
504
733
            amulet.raise_status(amulet.FAIL, msg=message)
505
734
 
506
 
    def test_lbaas_agent_config(self):
 
735
    def test_305_neutron_lbaas_agent_config(self):
507
736
        """Verify the data in the lbaas agent config file. This is only
508
737
           available since havana."""
 
738
        u.log.debug('Checking neutron gateway lbaas config file data...')
509
739
        if self._get_openstack_release() < self.precise_havana:
510
740
            return
511
741
 
513
743
        conf = '/etc/neutron/lbaas_agent.ini'
514
744
        expected = {
515
745
            'DEFAULT': {
516
 
                'periodic_interval': '10',
517
746
                'interface_driver': 'neutron.agent.linux.interface.'
518
747
                                    'OVSInterfaceDriver',
 
748
                'periodic_interval': '10',
519
749
                'ovs_use_veth': 'False',
520
 
                'device_driver': 'neutron.services.loadbalancer.drivers.'
521
 
                                 'haproxy.namespace_driver.HaproxyNSDriver'
522
750
            },
523
751
            'haproxy': {
524
752
                'loadbalancer_state_path': '$state_path/lbaas',
525
753
                'user_group': 'nogroup'
526
754
            }
527
755
        }
 
756
 
528
757
        if self._get_openstack_release() >= self.trusty_kilo:
529
 
            expected['DEFAULT']['device_driver'] = ('neutron_lbaas.services.' +
530
 
            'loadbalancer.drivers.haproxy.namespace_driver.HaproxyNSDriver')
 
758
            # Kilo or later
 
759
            expected['DEFAULT']['device_driver'] = \
 
760
                ('neutron_lbaas.services.loadbalancer.drivers.haproxy.'
 
761
                 'namespace_driver.HaproxyNSDriver')
 
762
        else:
 
763
            # Juno or earlier
 
764
            expected['DEFAULT']['device_driver'] = \
 
765
                ('neutron.services.loadbalancer.drivers.haproxy.'
 
766
                 'namespace_driver.HaproxyNSDriver')
531
767
 
532
768
        for section, pairs in expected.iteritems():
533
769
            ret = u.validate_config_data(unit, conf, section, pairs)
535
771
                message = "lbaas agent config error: {}".format(ret)
536
772
                amulet.raise_status(amulet.FAIL, msg=message)
537
773
 
538
 
    def test_metadata_agent_config(self):
 
774
    def test_306_neutron_metadata_agent_config(self):
539
775
        """Verify the data in the metadata agent config file."""
 
776
        u.log.debug('Checking neutron gateway metadata agent '
 
777
                    'config file data...')
540
778
        unit = self.neutron_gateway_sentry
541
779
        ep = self.keystone.service_catalog.url_for(service_type='identity',
542
780
                                                   endpoint_type='publicURL')
543
 
        neutron_gateway_relation = unit.relation('shared-db', 'mysql:shared-db')
544
 
        nova_cc_relation = self.nova_cc_sentry.relation(\
545
 
                                      'quantum-network-service',
546
 
                                      'neutron-gateway:quantum-network-service')
 
781
        ng_db_rel = unit.relation('shared-db',
 
782
                                  'mysql:shared-db')
 
783
        nova_cc_relation = self.nova_cc_sentry.relation(
 
784
            'quantum-network-service',
 
785
            'neutron-gateway:quantum-network-service')
547
786
 
548
787
        conf = '/etc/neutron/metadata_agent.ini'
549
788
        expected = {
550
789
            'auth_url': ep,
551
790
            'auth_region': 'RegionOne',
552
791
            'admin_tenant_name': 'services',
553
 
            'admin_user': 'quantum_s3_ec2_nova',
554
792
            'admin_password': nova_cc_relation['service_password'],
555
793
            'root_helper': 'sudo neutron-rootwrap '
556
 
                             '/etc/neutron/rootwrap.conf',
 
794
                           '/etc/neutron/rootwrap.conf',
557
795
            'state_path': '/var/lib/neutron',
558
 
            'nova_metadata_ip': neutron_gateway_relation['private-address'],
559
 
            'nova_metadata_port': '8775'
 
796
            'nova_metadata_ip': ng_db_rel['private-address'],
 
797
            'nova_metadata_port': '8775',
 
798
            'cache_url': 'memory://?default_ttl=5'
560
799
        }
 
800
        section = 'DEFAULT'
 
801
 
561
802
        if self._get_openstack_release() >= self.trusty_kilo:
 
803
            # Kilo or later
562
804
            expected['admin_user'] = 'nova'
563
 
 
564
 
        if self._get_openstack_release() >= self.precise_icehouse:
565
 
            expected['cache_url'] = 'memory://?default_ttl=5'
566
 
 
567
 
        ret = u.validate_config_data(unit, conf, 'DEFAULT', expected)
 
805
        else:
 
806
            # Juno or earlier
 
807
            expected['admin_user'] = 's3_ec2_nova'
 
808
 
 
809
        ret = u.validate_config_data(unit, conf, section, expected)
568
810
        if ret:
569
811
            message = "metadata agent config error: {}".format(ret)
570
812
            amulet.raise_status(amulet.FAIL, msg=message)
571
813
 
572
 
    def test_metering_agent_config(self):
 
814
    def test_307_neutron_metering_agent_config(self):
573
815
        """Verify the data in the metering agent config file.  This is only
574
816
           available since havana."""
575
 
        if self._get_openstack_release() < self.precise_havana:
576
 
            return
577
 
 
 
817
        u.log.debug('Checking neutron gateway metering agent '
 
818
                    'config file data...')
578
819
        unit = self.neutron_gateway_sentry
579
820
        conf = '/etc/neutron/metering_agent.ini'
580
821
        expected = {
586
827
                                'OVSInterfaceDriver',
587
828
            'use_namespaces': 'True'
588
829
        }
 
830
        section = 'DEFAULT'
589
831
 
590
 
        ret = u.validate_config_data(unit, conf, 'DEFAULT', expected)
 
832
        ret = u.validate_config_data(unit, conf, section, expected)
591
833
        if ret:
592
834
            message = "metering agent config error: {}".format(ret)
 
835
            amulet.raise_status(amulet.FAIL, msg=message)
593
836
 
594
 
    def test_nova_config(self):
 
837
    def test_308_neutron_nova_config(self):
595
838
        """Verify the data in the nova config file."""
 
839
        u.log.debug('Checking neutron gateway nova config file data...')
596
840
        unit = self.neutron_gateway_sentry
597
841
        conf = '/etc/nova/nova.conf'
598
 
        mysql_relation = self.mysql_sentry.relation('shared-db',
599
 
                                                    'neutron-gateway:shared-db')
600
 
        db_uri = "mysql://{}:{}@{}/{}".format('nova',
601
 
                                              mysql_relation['password'],
602
 
                                              mysql_relation['db_host'],
603
 
                                              'nova')
604
 
        rabbitmq_relation = self.rabbitmq_sentry.relation('amqp',
605
 
                                                         'neutron-gateway:amqp')
606
 
        nova_cc_relation = self.nova_cc_sentry.relation(\
607
 
                                      'quantum-network-service',
608
 
                                      'neutron-gateway:quantum-network-service')
 
842
 
 
843
        rabbitmq_relation = self.rmq_sentry.relation(
 
844
            'amqp', 'neutron-gateway:amqp')
 
845
        nova_cc_relation = self.nova_cc_sentry.relation(
 
846
            'quantum-network-service',
 
847
            'neutron-gateway:quantum-network-service')
609
848
        ep = self.keystone.service_catalog.url_for(service_type='identity',
610
849
                                                   endpoint_type='publicURL')
611
850
 
622
861
                'network_api_class': 'nova.network.neutronv2.api.API',
623
862
            }
624
863
        }
 
864
 
625
865
        if self._get_openstack_release() >= self.trusty_kilo:
626
 
            neutron = {
627
 
                'neutron': {
628
 
                    'auth_strategy': 'keystone',
629
 
                    'url': nova_cc_relation['quantum_url'],
630
 
                    'admin_tenant_name': 'services',
631
 
                    'admin_username': 'nova',
632
 
                    'admin_password': nova_cc_relation['service_password'],
633
 
                    'admin_auth_url': ep,
634
 
                    'service_metadata_proxy': 'True',
635
 
                }
636
 
            }
637
 
            oslo_concurrency = {
638
 
                'oslo_concurrency': {
639
 
                    'lock_path':'/var/lock/nova'
640
 
                }
641
 
            }
642
 
            oslo_messaging_rabbit = {
643
 
                'oslo_messaging_rabbit': {
644
 
                    'rabbit_userid': 'neutron',
645
 
                    'rabbit_virtual_host': 'openstack',
646
 
                    'rabbit_password': rabbitmq_relation['password'],
647
 
                    'rabbit_host': rabbitmq_relation['hostname'],
648
 
                }
649
 
            }
650
 
            expected.update(neutron)
651
 
            expected.update(oslo_concurrency)
652
 
            expected.update(oslo_messaging_rabbit)
 
866
            # Kilo or later
 
867
            expected['oslo_messaging_rabbit'] = {
 
868
                'rabbit_userid': 'neutron',
 
869
                'rabbit_virtual_host': 'openstack',
 
870
                'rabbit_password': rabbitmq_relation['password'],
 
871
                'rabbit_host': rabbitmq_relation['hostname'],
 
872
            }
 
873
            expected['oslo_concurrency'] = {
 
874
                'lock_path': '/var/lock/nova'
 
875
            }
 
876
            expected['neutron'] = {
 
877
                'auth_strategy': 'keystone',
 
878
                'url': nova_cc_relation['quantum_url'],
 
879
                'admin_tenant_name': 'services',
 
880
                'admin_username': 'nova',
 
881
                'admin_password': nova_cc_relation['service_password'],
 
882
                'admin_auth_url': ep,
 
883
                'service_metadata_proxy': 'True',
 
884
                'metadata_proxy_shared_secret': u.not_null
 
885
            }
653
886
        else:
654
 
            d = 'DEFAULT'
655
 
            expected[d]['lock_path'] = '/var/lock/nova'
656
 
            expected[d]['rabbit_userid'] = 'neutron'
657
 
            expected[d]['rabbit_virtual_host'] = 'openstack'
658
 
            expected[d]['rabbit_password'] = rabbitmq_relation['password']
659
 
            expected[d]['rabbit_host'] = rabbitmq_relation['hostname']
660
 
            expected[d]['service_neutron_metadata_proxy'] = 'True'
661
 
            expected[d]['neutron_auth_strategy'] = 'keystone'
662
 
            expected[d]['neutron_url'] = nova_cc_relation['quantum_url']
663
 
            expected[d]['neutron_admin_tenant_name'] = 'services'
664
 
            expected[d]['neutron_admin_username'] = 'quantum_s3_ec2_nova'
665
 
            expected[d]['neutron_admin_password'] = \
666
 
                                           nova_cc_relation['service_password']
667
 
            expected[d]['neutron_admin_auth_url'] = ep
 
887
            # Juno or earlier
 
888
            expected['DEFAULT'].update({
 
889
                'rabbit_userid': 'neutron',
 
890
                'rabbit_virtual_host': 'openstack',
 
891
                'rabbit_password': rabbitmq_relation['password'],
 
892
                'rabbit_host': rabbitmq_relation['hostname'],
 
893
                'lock_path': '/var/lock/nova',
 
894
                'neutron_auth_strategy': 'keystone',
 
895
                'neutron_url': nova_cc_relation['quantum_url'],
 
896
                'neutron_admin_tenant_name': 'services',
 
897
                'neutron_admin_username': 's3_ec2_nova',
 
898
                'neutron_admin_password': nova_cc_relation['service_password'],
 
899
                'neutron_admin_auth_url': ep,
 
900
                'service_neutron_metadata_proxy': 'True',
 
901
            })
668
902
 
669
903
        for section, pairs in expected.iteritems():
670
904
            ret = u.validate_config_data(unit, conf, section, pairs)
672
906
                message = "nova config error: {}".format(ret)
673
907
                amulet.raise_status(amulet.FAIL, msg=message)
674
908
 
675
 
    def test_ovs_neutron_plugin_config(self):
676
 
        """Verify the data in the ovs neutron plugin config file. The ovs
677
 
           plugin is not used by default since icehouse."""
678
 
        if self._get_openstack_release() >= self.precise_icehouse:
679
 
            return
680
 
 
681
 
        unit = self.neutron_gateway_sentry
682
 
        neutron_gateway_relation = unit.relation('shared-db', 'mysql:shared-db')
683
 
 
684
 
        conf = '/etc/neutron/plugins/openvswitch/ovs_neutron_plugin.ini'
685
 
        expected = {
686
 
            'ovs': {
687
 
                'local_ip': neutron_gateway_relation['private-address'],
688
 
                'tenant_network_type': 'gre',
689
 
                'enable_tunneling': 'True',
690
 
                'tunnel_id_ranges': '1:1000'
691
 
            },
692
 
            'agent': {
693
 
                'polling_interval': '10',
694
 
                'root_helper': 'sudo /usr/bin/neutron-rootwrap '
695
 
                '/etc/neutron/rootwrap.conf'
696
 
            }
697
 
        }
698
 
 
699
 
        for section, pairs in expected.iteritems():
700
 
            ret = u.validate_config_data(unit, conf, section, pairs)
701
 
            if ret:
702
 
                message = "ovs neutron plugin config error: {}".format(ret)
703
 
                amulet.raise_status(amulet.FAIL, msg=message)
704
 
 
705
 
    def test_vpn_agent_config(self):
 
909
    def test_309_neutron_vpn_agent_config(self):
706
910
        """Verify the data in the vpn agent config file.  This isn't available
707
911
           prior to havana."""
708
 
        if self._get_openstack_release() < self.precise_havana:
709
 
            return
710
 
 
 
912
        u.log.debug('Checking neutron gateway vpn agent config file data...')
711
913
        unit = self.neutron_gateway_sentry
712
914
        conf = '/etc/neutron/vpn_agent.ini'
713
915
        expected = {
714
 
            'vpnagent': {
 
916
            'ipsec': {
 
917
                'ipsec_status_check_interval': '60'
 
918
            }
 
919
        }
 
920
 
 
921
        if self._get_openstack_release() >= self.trusty_kilo:
 
922
            # Kilo or later
 
923
            expected['vpnagent'] = {
 
924
                'vpn_device_driver': 'neutron_vpnaas.services.vpn.'
 
925
                                     'device_drivers.ipsec.OpenSwanDriver'
 
926
            }
 
927
        else:
 
928
            # Juno or earlier
 
929
            expected['vpnagent'] = {
715
930
                'vpn_device_driver': 'neutron.services.vpn.device_drivers.'
716
931
                                     'ipsec.OpenSwanDriver'
717
 
            },
718
 
            'ipsec': {
719
 
                'ipsec_status_check_interval': '60'
720
932
            }
721
 
        }
722
 
        if self._get_openstack_release() >= self.trusty_kilo:
723
 
            expected['vpnagent']['vpn_device_driver'] = ('neutron_vpnaas.' +
724
 
                'services.vpn.device_drivers.ipsec.OpenSwanDriver')
725
933
 
726
934
        for section, pairs in expected.iteritems():
727
935
            ret = u.validate_config_data(unit, conf, section, pairs)
729
937
                message = "vpn agent config error: {}".format(ret)
730
938
                amulet.raise_status(amulet.FAIL, msg=message)
731
939
 
732
 
    def test_create_network(self):
 
940
    def test_400_create_network(self):
733
941
        """Create a network, verify that it exists, and then delete it."""
 
942
        u.log.debug('Creating neutron network...')
734
943
        self.neutron.format = 'json'
735
944
        net_name = 'ext_net'
736
945
 
737
 
        #Verify that the network doesn't exist
 
946
        # Verify that the network doesn't exist
738
947
        networks = self.neutron.list_networks(name=net_name)
739
948
        net_count = len(networks['networks'])
740
949
        if net_count != 0:
743
952
 
744
953
        # Create a network and verify that it exists
745
954
        network = {'name': net_name}
746
 
        self.neutron.create_network({'network':network})
 
955
        self.neutron.create_network({'network': network})
747
956
 
748
957
        networks = self.neutron.list_networks(name=net_name)
 
958
        u.log.debug('Networks: {}'.format(networks))
749
959
        net_len = len(networks['networks'])
750
960
        if net_len != 1:
751
961
            msg = "Expected 1 network, found {}".format(net_len)
752
962
            amulet.raise_status(amulet.FAIL, msg=msg)
753
963
 
 
964
        u.log.debug('Confirming new neutron network...')
754
965
        network = networks['networks'][0]
755
966
        if network['name'] != net_name:
756
967
            amulet.raise_status(amulet.FAIL, msg="network ext_net not found")
757
968
 
758
 
        #Cleanup
 
969
        # Cleanup
 
970
        u.log.debug('Deleting neutron network...')
759
971
        self.neutron.delete_network(network['id'])
 
972
 
 
973
    def test_900_restart_on_config_change(self):
 
974
        """Verify that the specified services are restarted when the
 
975
        config is changed."""
 
976
 
 
977
        sentry = self.neutron_gateway_sentry
 
978
        juju_service = 'neutron-gateway'
 
979
 
 
980
        # Expected default and alternate values
 
981
        set_default = {'debug': 'False'}
 
982
        set_alternate = {'debug': 'True'}
 
983
 
 
984
        # Services which are expected to restart upon config change,
 
985
        # and corresponding config files affected by the change
 
986
        conf_file = '/etc/neutron/neutron.conf'
 
987
        services = {
 
988
            'neutron-dhcp-agent': conf_file,
 
989
            'neutron-lbaas-agent': conf_file,
 
990
            'neutron-metadata-agent': conf_file,
 
991
            'neutron-metering-agent': conf_file,
 
992
            'neutron-openvswitch-agent': conf_file,
 
993
        }
 
994
 
 
995
        if self._get_openstack_release() <= self.trusty_juno:
 
996
            services.update({'neutron-vpn-agent': conf_file})
 
997
 
 
998
        # Make config change, check for svc restart, conf file mod time change
 
999
        u.log.debug('Making config change on {}...'.format(juju_service))
 
1000
        mtime = u.get_sentry_time(sentry)
 
1001
        self.d.configure(juju_service, set_alternate)
 
1002
 
 
1003
        # sleep_time = 90
 
1004
        for s, conf_file in services.iteritems():
 
1005
            u.log.debug("Checking that service restarted: {}".format(s))
 
1006
            if not u.validate_service_config_changed(sentry, mtime, s,
 
1007
                                                     conf_file):
 
1008
                self.d.configure(juju_service, set_default)
 
1009
                msg = "service {} didn't restart after config change".format(s)
 
1010
                amulet.raise_status(amulet.FAIL, msg=msg)
 
1011
 
 
1012
            # Only do initial sleep on first service check
 
1013
            # sleep_time = 0
 
1014
 
 
1015
        self.d.configure(juju_service, set_default)