~hopem/charms/trusty/keystone/reloads

« back to all changes in this revision

Viewing changes to hooks/keystone_hooks.py

  • Committer: Edward Hope-Morley
  • Date: 2015-01-05 17:49:38 UTC
  • Revision ID: edward.hope-morley@canonical.com-20150105174938-zp8ifxfuzwntg8m7
[hopem,r=]

Fixes ssl cert sycnhronisation across peers

Closes-Bug: 1317782

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
#!/usr/bin/python
2
 
 
3
2
import hashlib
4
3
import os
 
4
import re
 
5
import stat
5
6
import sys
6
7
import time
7
8
 
16
17
    is_relation_made,
17
18
    log,
18
19
    local_unit,
 
20
    WARNING,
19
21
    ERROR,
20
22
    relation_get,
21
23
    relation_ids,
57
59
    STORED_PASSWD,
58
60
    setup_ipv6,
59
61
    send_notifications,
 
62
    check_peer_actions,
 
63
    CA_CERT_PATH,
 
64
    ensure_permissions,
60
65
)
61
66
 
62
67
from charmhelpers.contrib.hahelpers.cluster import (
63
 
    eligible_leader,
64
 
    is_leader,
 
68
    is_elected_leader,
65
69
    get_hacluster_config,
66
70
)
67
71
 
109
113
 
110
114
    check_call(['chmod', '-R', 'g+wrx', '/var/lib/keystone/'])
111
115
 
 
116
    # Ensure unison can write to certs dir.
 
117
    # FIXME: need to a better way around this e.g. move cert to it's own dir
 
118
    # and give that unison permissions.
 
119
    path = os.path.dirname(CA_CERT_PATH)
 
120
    perms = int(oct(stat.S_IMODE(os.stat(path).st_mode) |
 
121
                    (stat.S_IWGRP | stat.S_IXGRP)), base=8)
 
122
    ensure_permissions(path, group='keystone', perms=perms)
 
123
 
112
124
    save_script_rc()
113
125
    configure_https()
114
126
    CONFIGS.write_all()
115
 
    if eligible_leader(CLUSTER_RES):
 
127
 
 
128
    if is_elected_leader(CLUSTER_RES):
116
129
        migrate_database()
117
130
        ensure_initial_admin(config)
118
131
        log('Firing identity_changed hook for all related services.')
121
134
        for r_id in relation_ids('identity-service'):
122
135
            for unit in relation_list(r_id):
123
136
                identity_changed(relation_id=r_id,
124
 
                                 remote_unit=unit)
 
137
                                 remote_unit=unit, sync_certs=False)
 
138
 
 
139
    synchronize_ca()
125
140
 
126
141
    [cluster_joined(rid) for rid in relation_ids('cluster')]
127
142
 
163
178
        log('shared-db relation incomplete. Peer not ready?')
164
179
    else:
165
180
        CONFIGS.write(KEYSTONE_CONF)
166
 
        if eligible_leader(CLUSTER_RES):
 
181
        if is_elected_leader(CLUSTER_RES):
167
182
            # Bugs 1353135 & 1187508. Dbs can appear to be ready before the
168
183
            # units acl entry has been added. So, if the db supports passing
169
184
            # a list of permitted units then check if we're in the list.
188
203
        log('pgsql-db relation incomplete. Peer not ready?')
189
204
    else:
190
205
        CONFIGS.write(KEYSTONE_CONF)
191
 
        if eligible_leader(CLUSTER_RES):
 
206
        if is_elected_leader(CLUSTER_RES):
192
207
            migrate_database()
193
208
            ensure_initial_admin(config)
194
209
            # Ensure any existing service entries are updated in the
199
214
 
200
215
 
201
216
@hooks.hook('identity-service-relation-changed')
202
 
def identity_changed(relation_id=None, remote_unit=None):
 
217
def identity_changed(relation_id=None, remote_unit=None, sync_certs=True):
203
218
    notifications = {}
204
 
    if eligible_leader(CLUSTER_RES):
205
 
        add_service_to_keystone(relation_id, remote_unit)
206
 
        synchronize_ca()
 
219
    if is_elected_leader(CLUSTER_RES):
 
220
        # Catch database not configured error and defer until db ready
 
221
        from keystoneclient.apiclient.exceptions import InternalServerError
 
222
        try:
 
223
            add_service_to_keystone(relation_id, remote_unit)
 
224
        except InternalServerError as exc:
 
225
            key = re.compile("'keystone\..+' doesn't exist")
 
226
            if re.search(key, exc.message):
 
227
                log("Keystone database not yet ready (InternalServerError "
 
228
                    "raised) - deferring until *-db relation completes.",
 
229
                    level=WARNING)
 
230
                return
 
231
 
 
232
            log("Unexpected exception occurred", level=ERROR)
 
233
            raise
 
234
 
 
235
        CONFIGS.write_all()
 
236
        if sync_certs:
 
237
            synchronize_ca()
207
238
 
208
239
        settings = relation_get(rid=relation_id, unit=remote_unit)
209
240
        service = settings.get('service', None)
257
288
            'cluster-relation-departed')
258
289
@restart_on_change(restart_map(), stopstart=True)
259
290
def cluster_changed():
 
291
    check_peer_actions()
 
292
 
260
293
    # NOTE(jamespage) re-echo passwords for peer storage
261
 
    peer_echo(includes=['_passwd', 'identity-service:'])
 
294
    echo_whitelist = ['_passwd', 'identity-service:', 'ssl-cert-master']
 
295
    peer_echo(includes=echo_whitelist)
262
296
    unison.ssh_authorized_peers(user=SSH_USER,
263
297
                                group='keystone',
264
298
                                peer_interface='cluster',
265
299
                                ensure_local_user=True)
266
 
    synchronize_ca()
267
300
    CONFIGS.write_all()
268
301
    for r_id in relation_ids('identity-service'):
269
302
        for unit in relation_list(r_id):
270
 
            identity_changed(relation_id=r_id,
271
 
                             remote_unit=unit)
 
303
            identity_changed(relation_id=r_id, remote_unit=unit,
 
304
                             sync_certs=False)
 
305
 
 
306
    synchronize_ca()
272
307
 
273
308
 
274
309
@hooks.hook('ha-relation-joined')
325
360
def ha_changed():
326
361
    clustered = relation_get('clustered')
327
362
    CONFIGS.write_all()
328
 
    if (clustered is not None and
329
 
            is_leader(CLUSTER_RES)):
 
363
    if clustered is not None and is_elected_leader(CLUSTER_RES):
330
364
        ensure_initial_admin(config)
331
365
        log('Cluster configured, notifying other services and updating '
332
366
            'keystone endpoint configuration')
333
367
    for rid in relation_ids('identity-service'):
334
368
        for unit in related_units(rid):
335
 
            identity_changed(relation_id=rid, remote_unit=unit)
 
369
            identity_changed(relation_id=rid, remote_unit=unit,
 
370
                             sync_certs=False)
 
371
 
 
372
    synchronize_ca()
336
373
 
337
374
 
338
375
@hooks.hook('identity-admin-relation-changed')
375
412
                                group='keystone',
376
413
                                peer_interface='cluster',
377
414
                                ensure_local_user=True)
378
 
    synchronize_ca()
379
 
    if eligible_leader(CLUSTER_RES):
 
415
    if is_elected_leader(CLUSTER_RES):
380
416
        log('Cluster leader - ensuring endpoint configuration'
381
417
            ' is up to date')
382
418
        time.sleep(10)
385
421
        for r_id in relation_ids('identity-service'):
386
422
            for unit in relation_list(r_id):
387
423
                identity_changed(relation_id=r_id,
388
 
                                 remote_unit=unit)
 
424
                                 remote_unit=unit, sync_certs=False)
389
425
    CONFIGS.write_all()
 
426
    synchronize_ca()
390
427
 
391
428
 
392
429
def main():