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