github.com/niedbalski/juju@v0.0.0-20190215020005-8ff100488e47/acceptancetests/repository/xenial/mysql/hooks/shared-db-relation-joined (about) 1 #!/usr/bin/python 2 # 3 # Create relations between a shared database to many peers. 4 # Join does nothing. Peer requests access to $DATABASE from $REMOTE_HOST. 5 # It's up to the hooks to ensure database exists, peer has access and 6 # clean up grants after a broken/departed peer (TODO) 7 # 8 # Author: Adam Gandelman <adam.gandelman@canonical.com> 9 10 11 from common import ( 12 database_exists, 13 create_database, 14 grant_exists, 15 create_grant 16 ) 17 import subprocess 18 import json 19 import socket 20 import os 21 import lib.utils as utils 22 import lib.cluster_utils as cluster 23 24 LEADER_RES = 'res_mysql_vip' 25 26 27 def pwgen(): 28 return str(subprocess.check_output(['pwgen', '-s', '16'])).strip() 29 30 31 def relation_get(): 32 return json.loads(subprocess.check_output( 33 ['relation-get', 34 '--format', 35 'json'] 36 ) 37 ) 38 39 40 def shared_db_changed(): 41 42 def configure_db(hostname, 43 database, 44 username): 45 passwd_file = "/var/lib/mysql/mysql-{}.passwd"\ 46 .format(username) 47 if hostname != local_hostname: 48 remote_ip = socket.gethostbyname(hostname) 49 else: 50 remote_ip = '127.0.0.1' 51 52 if not os.path.exists(passwd_file): 53 password = pwgen() 54 with open(passwd_file, 'w') as pfile: 55 pfile.write(password) 56 else: 57 with open(passwd_file) as pfile: 58 password = pfile.read().strip() 59 60 if not database_exists(database): 61 create_database(database) 62 if not grant_exists(database, 63 username, 64 remote_ip): 65 create_grant(database, 66 username, 67 remote_ip, password) 68 return password 69 70 if not cluster.eligible_leader(LEADER_RES): 71 utils.juju_log('INFO', 72 'MySQL service is peered, bailing shared-db relation' 73 ' as this service unit is not the leader') 74 return 75 76 settings = relation_get() 77 local_hostname = utils.unit_get('private-address') 78 singleset = set([ 79 'database', 80 'username', 81 'hostname' 82 ]) 83 84 if singleset.issubset(settings): 85 # Process a single database configuration 86 password = configure_db(settings['hostname'], 87 settings['database'], 88 settings['username']) 89 if not cluster.is_clustered(): 90 utils.relation_set(db_host=local_hostname, 91 password=password) 92 else: 93 utils.relation_set(db_host=utils.config_get("vip"), 94 password=password) 95 96 else: 97 # Process multiple database setup requests. 98 # from incoming relation data: 99 # nova_database=xxx nova_username=xxx nova_hostname=xxx 100 # quantum_database=xxx quantum_username=xxx quantum_hostname=xxx 101 # create 102 #{ 103 # "nova": { 104 # "username": xxx, 105 # "database": xxx, 106 # "hostname": xxx 107 # }, 108 # "quantum": { 109 # "username": xxx, 110 # "database": xxx, 111 # "hostname": xxx 112 # } 113 #} 114 # 115 databases = {} 116 for k, v in settings.iteritems(): 117 db = k.split('_')[0] 118 x = '_'.join(k.split('_')[1:]) 119 if db not in databases: 120 databases[db] = {} 121 databases[db][x] = v 122 return_data = {} 123 for db in databases: 124 if singleset.issubset(databases[db]): 125 return_data['_'.join([db, 'password'])] = \ 126 configure_db(databases[db]['hostname'], 127 databases[db]['database'], 128 databases[db]['username']) 129 if len(return_data) > 0: 130 utils.relation_set(**return_data) 131 if not cluster.is_clustered(): 132 utils.relation_set(db_host=local_hostname) 133 else: 134 utils.relation_set(db_host=utils.config_get("vip")) 135 136 hooks = { 137 "shared-db-relation-changed": shared_db_changed 138 } 139 140 utils.do_hooks(hooks)