github.com/niedbalski/juju@v0.0.0-20190215020005-8ff100488e47/acceptancetests/repository/xenial/mysql/hooks/common.py (about) 1 # vim: syntax=python 2 3 import os 4 import sys 5 import MySQLdb 6 import subprocess 7 import uuid 8 9 def get_service_user_file(service): 10 return '/var/lib/mysql/%s.service_user2' % service 11 12 13 def get_service_user(service): 14 if service == '': 15 return (None, None) 16 sfile = get_service_user_file(service) 17 if os.path.exists(sfile): 18 with open(sfile, 'r') as f: 19 return (f.readline().strip(), f.readline().strip()) 20 (suser, service_password) = subprocess.check_output(['pwgen', '-N 2', '15']).strip().split("\n") 21 with open(sfile, 'w') as f: 22 f.write("%s\n" % suser) 23 f.write("%s\n" % service_password) 24 f.flush() 25 return (suser, service_password) 26 27 28 def cleanup_service_user(service): 29 os.unlink(get_service_user_file(service)) 30 31 32 relation_id = os.environ.get('JUJU_RELATION_ID') 33 change_unit = os.environ.get('JUJU_REMOTE_UNIT') 34 35 # We'll name the database the same as the service. 36 database_name_file = '.%s_database_name' % (relation_id) 37 # change_unit will be None on broken hooks 38 database_name = '' 39 if change_unit: 40 database_name, _ = change_unit.split("/") 41 with open(database_name_file, 'w') as dbnf: 42 dbnf.write("%s\n" % database_name) 43 dbnf.flush() 44 elif os.path.exists(database_name_file): 45 with open(database_name_file, 'r') as dbname: 46 database_name = dbname.readline().strip() 47 else: 48 print 'No established database and no REMOTE_UNIT.' 49 # A user per service unit so we can deny access quickly 50 user, service_password = get_service_user(database_name) 51 connection = None 52 lastrun_path = '/var/lib/juju/%s.%s.lastrun' % (database_name,user) 53 slave_configured_path = '/var/lib/juju.slave.configured.for.%s' % database_name 54 slave_configured = os.path.exists(slave_configured_path) 55 slave = os.path.exists('/var/lib/juju/i.am.a.slave') 56 broken_path = '/var/lib/juju/%s.mysql.broken' % database_name 57 broken = os.path.exists(broken_path) 58 59 def get_db_cursor(): 60 # Connect to mysql 61 passwd = open("/var/lib/mysql/mysql.passwd").read().strip() 62 connection = MySQLdb.connect(user="root", host="localhost", passwd=passwd) 63 return connection.cursor() 64 65 66 def database_exists(db_name): 67 cursor = get_db_cursor() 68 try: 69 cursor.execute("SHOW DATABASES") 70 databases = [i[0] for i in cursor.fetchall()] 71 finally: 72 cursor.close() 73 return db_name in databases 74 75 76 def create_database(db_name): 77 cursor = get_db_cursor() 78 try: 79 cursor.execute("CREATE DATABASE {}".format(db_name)) 80 finally: 81 cursor.close() 82 83 84 def grant_exists(db_name, db_user, remote_ip): 85 cursor = get_db_cursor() 86 try: 87 cursor.execute("SHOW GRANTS for '{}'@'{}'".format(db_user, 88 remote_ip)) 89 grants = [i[0] for i in cursor.fetchall()] 90 except MySQLdb.OperationalError: 91 print "No grants found" 92 return False 93 finally: 94 cursor.close() 95 return "GRANT ALL PRIVILEGES ON `{}`".format(db_name) in grants 96 97 98 def create_grant(db_name, db_user, 99 remote_ip, password): 100 cursor = get_db_cursor() 101 try: 102 cursor.execute("GRANT ALL PRIVILEGES ON {}.* TO '{}'@'{}' "\ 103 "IDENTIFIED BY '{}'".format(db_name, 104 db_user, 105 remote_ip, 106 password)) 107 finally: 108 cursor.close() 109 110 111 def cleanup_grant(db_user, 112 remote_ip): 113 cursor = get_db_cursor() 114 try: 115 cursor.execute("DROP FROM mysql.user WHERE user='{}' "\ 116 "AND HOST='{}'".format(db_user, 117 remote_ip)) 118 finally: 119 cursor.close()