~nick-moffitt/charms/precise/mysql/mysql-shopt-is-a-shell-builtin

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
# vim: syntax=python

import os
import sys
import MySQLdb
import subprocess
import uuid

def get_service_user_file(service):
    return '/var/lib/juju/%s.service_user2' % service


def get_service_user(service):
    if service == '':
        return (None, None)
    sfile = get_service_user_file(service)
    if os.path.exists(sfile):
        with open(sfile, 'r') as f:
            return (f.readline().strip(), f.readline().strip())
    (suser, service_password) = subprocess.check_output(['pwgen', '-N 2', '15']).strip().split("\n")
    with open(sfile, 'w') as f:
        f.write("%s\n" % suser)
        f.write("%s\n" % service_password)
        f.flush()
    return (suser, service_password)


def cleanup_service_user(service):
    os.unlink(get_service_user_file(service))


relation_id = os.environ.get('JUJU_RELATION_ID')
change_unit = os.environ.get('JUJU_REMOTE_UNIT')

# We'll name the database the same as the service.
database_name_file = '.%s_database_name' % (relation_id)
# change_unit will be None on broken hooks
database_name = ''
if change_unit:
    database_name, _ = change_unit.split("/")
    with open(database_name_file, 'w') as dbnf:
        dbnf.write("%s\n" % database_name)
        dbnf.flush()
elif os.path.exists(database_name_file):
    with open(database_name_file, 'r') as dbname:
        database_name = dbname.readline().strip()
else:
    print 'No established database and no REMOTE_UNIT.'
# A user per service unit so we can deny access quickly
user, service_password = get_service_user(database_name)
connection = None
lastrun_path = '/var/lib/juju/%s.%s.lastrun' % (database_name,user)
slave_configured_path = '/var/lib/juju.slave.configured.for.%s' % database_name
slave_configured = os.path.exists(slave_configured_path)
slave = os.path.exists('/var/lib/juju/i.am.a.slave')
broken_path = '/var/lib/juju/%s.mysql.broken' % database_name
broken = os.path.exists(broken_path)

def get_db_cursor():
    # Connect to mysql
    passwd = open("/var/lib/juju/mysql.passwd").read().strip()
    connection = MySQLdb.connect(user="root", host="localhost", passwd=passwd)
    return connection.cursor()


def database_exists(db_name):
    cursor = get_db_cursor()
    try:
        cursor.execute("SHOW DATABASES")
        databases = [i[0] for i in cursor.fetchall()]
    finally:
        cursor.close()
    return db_name in databases


def create_database(db_name):
    cursor = get_db_cursor()
    try:
        cursor.execute("CREATE DATABASE {}".format(db_name))
    finally:
        cursor.close()


def grant_exists(db_name, db_user, remote_ip):
    cursor = get_db_cursor()
    try:
        cursor.execute("SHOW GRANTS for '{}'@'{}'".format(db_user,
                                                          remote_ip))
        grants = [i[0] for i in cursor.fetchall()]
    except MySQLdb.OperationalError:
        print "No grants found"
        return False
    finally:
        cursor.close()
    return "GRANT ALL PRIVILEGES ON `{}`".format(db_name) in grants


def create_grant(db_name, db_user,
                 remote_ip, password):
    cursor = get_db_cursor()
    try:
        cursor.execute("GRANT ALL PRIVILEGES ON {}.* TO '{}'@'{}' "\
                       "IDENTIFIED BY '{}'".format(db_name,
                                                   db_user,
                                                   remote_ip,
                                                   password))
    finally:
        cursor.close()


def cleanup_grant(db_user,
                  remote_ip):
    cursor = get_db_cursor()
    try:
        cursor.execute("DROP FROM mysql.user WHERE user='{}' "\
                       "AND HOST='{}'".format(db_user,
                                              remote_ip))
    finally:
        cursor.close()