2014-10-14 13:50:19 +00:00
|
|
|
import textwrap
|
|
|
|
|
2014-07-09 16:17:43 +00:00
|
|
|
from django.utils.translation import ugettext_lazy as _
|
|
|
|
|
2015-04-05 18:02:36 +00:00
|
|
|
from orchestra.contrib.orchestration import ServiceController, replace
|
2015-04-05 10:46:24 +00:00
|
|
|
from orchestra.contrib.resources import ServiceMonitor
|
2014-05-08 16:59:35 +00:00
|
|
|
|
|
|
|
from . import settings
|
|
|
|
|
|
|
|
|
2016-03-08 10:16:49 +00:00
|
|
|
class MySQLController(ServiceController):
|
2015-04-23 19:46:23 +00:00
|
|
|
"""
|
2015-04-24 11:39:20 +00:00
|
|
|
Simple backend for creating MySQL databases using <tt>CREATE DATABASE</tt> statement.
|
2015-04-23 19:46:23 +00:00
|
|
|
"""
|
2014-05-08 16:59:35 +00:00
|
|
|
verbose_name = "MySQL database"
|
|
|
|
model = 'databases.Database'
|
2015-03-04 21:06:16 +00:00
|
|
|
default_route_match = "database.type == 'mysql'"
|
2015-04-24 11:39:20 +00:00
|
|
|
doc_settings = (settings,
|
|
|
|
('DATABASES_DEFAULT_HOST',)
|
|
|
|
)
|
2014-05-08 16:59:35 +00:00
|
|
|
|
|
|
|
def save(self, database):
|
2014-10-17 10:04:47 +00:00
|
|
|
if database.type != database.MYSQL:
|
|
|
|
return
|
2014-10-15 19:29:58 +00:00
|
|
|
context = self.get_context(database)
|
2015-04-21 13:12:48 +00:00
|
|
|
# Not available on delete()
|
|
|
|
context['owner'] = database.owner
|
2015-05-21 17:53:59 +00:00
|
|
|
self.append(textwrap.dedent("""
|
|
|
|
# Create database and re-set permissions
|
|
|
|
mysql -e 'CREATE DATABASE `%(database)s`;' || true
|
|
|
|
mysql mysql -e 'DELETE FROM db WHERE db = "%(database)s";'\
|
|
|
|
""") % context
|
|
|
|
)
|
2014-10-15 19:29:58 +00:00
|
|
|
for user in database.users.all():
|
|
|
|
context.update({
|
|
|
|
'username': user.username,
|
|
|
|
'grant': 'WITH GRANT OPTION' if user == context['owner'] else ''
|
|
|
|
})
|
2014-10-14 13:50:19 +00:00
|
|
|
self.append(textwrap.dedent("""\
|
2015-05-21 17:53:59 +00:00
|
|
|
mysql -e 'GRANT ALL PRIVILEGES ON `%(database)s`.* TO "%(username)s"@"%(host)s" %(grant)s;'\
|
2015-03-10 16:57:23 +00:00
|
|
|
""") % context
|
|
|
|
)
|
2014-05-08 16:59:35 +00:00
|
|
|
|
|
|
|
def delete(self, database):
|
2014-10-17 10:04:47 +00:00
|
|
|
if database.type != database.MYSQL:
|
|
|
|
return
|
2014-10-15 19:29:58 +00:00
|
|
|
context = self.get_context(database)
|
2015-05-21 17:53:59 +00:00
|
|
|
self.append(textwrap.dedent("""
|
|
|
|
# Remove database %(database)s
|
|
|
|
mysql -e 'DROP DATABASE `%(database)s`;' || exit_code=$?
|
|
|
|
mysql mysql -e 'DELETE FROM db WHERE db = "%(database)s";'\
|
|
|
|
""") % context
|
|
|
|
)
|
|
|
|
|
2014-05-08 16:59:35 +00:00
|
|
|
def commit(self):
|
2015-05-21 17:53:59 +00:00
|
|
|
self.append(textwrap.dedent("""
|
|
|
|
# Apply permissions
|
|
|
|
mysql -e 'FLUSH PRIVILEGES;'\
|
|
|
|
""")
|
|
|
|
)
|
2016-03-08 10:16:49 +00:00
|
|
|
super(MySQLController, self).commit()
|
2014-05-08 16:59:35 +00:00
|
|
|
|
|
|
|
def get_context(self, database):
|
2015-04-05 18:02:36 +00:00
|
|
|
context = {
|
2014-05-08 16:59:35 +00:00
|
|
|
'database': database.name,
|
|
|
|
'host': settings.DATABASES_DEFAULT_HOST,
|
|
|
|
}
|
2015-04-05 18:02:36 +00:00
|
|
|
return replace(replace(context, "'", '"'), ';', '')
|
2014-05-08 16:59:35 +00:00
|
|
|
|
|
|
|
|
2016-03-08 10:16:49 +00:00
|
|
|
class MySQLUserController(ServiceController):
|
2015-04-23 19:46:23 +00:00
|
|
|
"""
|
2015-04-24 11:39:20 +00:00
|
|
|
Simple backend for creating MySQL users using <tt>CREATE USER</tt> statement.
|
|
|
|
"""
|
2014-05-08 16:59:35 +00:00
|
|
|
verbose_name = "MySQL user"
|
|
|
|
model = 'databases.DatabaseUser'
|
2015-03-04 21:06:16 +00:00
|
|
|
default_route_match = "databaseuser.type == 'mysql'"
|
2015-04-24 11:39:20 +00:00
|
|
|
doc_settings = (settings,
|
|
|
|
('DATABASES_DEFAULT_HOST',)
|
|
|
|
)
|
2014-05-08 16:59:35 +00:00
|
|
|
|
2014-10-09 17:04:12 +00:00
|
|
|
def save(self, user):
|
2014-10-17 10:04:47 +00:00
|
|
|
if user.type != user.MYSQL:
|
|
|
|
return
|
2014-10-15 19:29:58 +00:00
|
|
|
context = self.get_context(user)
|
|
|
|
self.append(textwrap.dedent("""\
|
2015-05-21 17:53:59 +00:00
|
|
|
# Create user %(username)s
|
2015-09-30 13:22:17 +00:00
|
|
|
mysql -e 'CREATE USER "%(username)s"@"%(host)s";' || true # User already exists
|
2015-05-21 17:53:59 +00:00
|
|
|
mysql -e 'UPDATE mysql.user SET Password="%(password)s" WHERE User="%(username)s";'\
|
2015-03-10 16:57:23 +00:00
|
|
|
""") % context
|
|
|
|
)
|
2014-05-08 16:59:35 +00:00
|
|
|
|
2014-10-09 17:04:12 +00:00
|
|
|
def delete(self, user):
|
2014-10-17 10:04:47 +00:00
|
|
|
if user.type != user.MYSQL:
|
|
|
|
return
|
2014-10-15 19:29:58 +00:00
|
|
|
context = self.get_context(user)
|
2015-05-21 17:53:59 +00:00
|
|
|
self.append(textwrap.dedent("""
|
|
|
|
# Delete user %(username)s
|
2015-04-07 15:14:49 +00:00
|
|
|
mysql -e 'DROP USER "%(username)s"@"%(host)s";' || exit_code=$? \
|
2015-03-10 16:57:23 +00:00
|
|
|
""") % context
|
|
|
|
)
|
2014-10-14 13:50:19 +00:00
|
|
|
|
|
|
|
def commit(self):
|
2015-05-21 17:53:59 +00:00
|
|
|
self.append("# Apply permissions")
|
2014-10-14 13:50:19 +00:00
|
|
|
self.append("mysql -e 'FLUSH PRIVILEGES;'")
|
2014-05-08 16:59:35 +00:00
|
|
|
|
2014-10-09 17:04:12 +00:00
|
|
|
def get_context(self, user):
|
2015-04-05 18:02:36 +00:00
|
|
|
context = {
|
2014-10-09 17:04:12 +00:00
|
|
|
'username': user.username,
|
|
|
|
'password': user.password,
|
2014-05-08 16:59:35 +00:00
|
|
|
'host': settings.DATABASES_DEFAULT_HOST,
|
|
|
|
}
|
2015-04-05 18:02:36 +00:00
|
|
|
return replace(replace(context, "'", '"'), ';', '')
|
2014-05-08 16:59:35 +00:00
|
|
|
|
|
|
|
|
2014-07-09 16:17:43 +00:00
|
|
|
class MysqlDisk(ServiceMonitor):
|
2015-04-23 19:46:23 +00:00
|
|
|
"""
|
2015-04-24 11:39:20 +00:00
|
|
|
<tt>du -bs <database_path></tt>
|
2015-04-23 19:46:23 +00:00
|
|
|
Implements triggers for resource limit exceeded and recovery, disabling insert and create privileges.
|
|
|
|
"""
|
2014-09-14 09:52:45 +00:00
|
|
|
model = 'databases.Database'
|
2014-07-09 16:17:43 +00:00
|
|
|
verbose_name = _("MySQL disk")
|
2015-08-04 09:47:39 +00:00
|
|
|
delete_old_equal_values = True
|
2016-05-27 09:54:46 +00:00
|
|
|
doc_settings = (settings,
|
|
|
|
('DATABASES_MYSQL_DB_DIR',)
|
|
|
|
)
|
|
|
|
mysql_db_dir = settings.DATABASES_MYSQL_DB_DIR
|
2014-07-16 15:20:16 +00:00
|
|
|
|
|
|
|
def exceeded(self, db):
|
2014-10-17 10:04:47 +00:00
|
|
|
if db.type != db.MYSQL:
|
|
|
|
return
|
2014-09-26 15:05:20 +00:00
|
|
|
context = self.get_context(db)
|
2014-10-14 13:50:19 +00:00
|
|
|
self.append(textwrap.dedent("""\
|
2014-11-18 13:59:21 +00:00
|
|
|
mysql -e 'UPDATE db SET Insert_priv="N", Create_priv="N" WHERE Db="%(db_name)s";'\
|
2015-03-10 16:57:23 +00:00
|
|
|
""") % context
|
|
|
|
)
|
2014-07-16 15:20:16 +00:00
|
|
|
|
|
|
|
def recovery(self, db):
|
2014-10-17 10:04:47 +00:00
|
|
|
if db.type != db.MYSQL:
|
|
|
|
return
|
2014-09-26 15:05:20 +00:00
|
|
|
context = self.get_context(db)
|
2014-10-14 13:50:19 +00:00
|
|
|
self.append(textwrap.dedent("""\
|
2014-11-18 13:59:21 +00:00
|
|
|
mysql -e 'UPDATE db SET Insert_priv="Y", Create_priv="Y" WHERE Db="%(db_name)s";'\
|
2015-03-10 16:57:23 +00:00
|
|
|
""") % context
|
|
|
|
)
|
2014-11-18 13:59:21 +00:00
|
|
|
|
|
|
|
def prepare(self):
|
2016-05-27 09:54:46 +00:00
|
|
|
super().prepare()
|
|
|
|
context = {
|
|
|
|
'mysql_db_dir': self.mysql_db_dir,
|
|
|
|
}
|
2014-11-18 13:59:21 +00:00
|
|
|
self.append(textwrap.dedent("""\
|
2016-05-27 09:54:46 +00:00
|
|
|
function monitor_mysql () {
|
|
|
|
{ SIZE=$(du -bs "%(mysql_db_dir)s/$1") && echo $SIZE || echo 0; } | awk {'print $1'}
|
|
|
|
}""") % context)
|
2014-11-18 13:59:21 +00:00
|
|
|
# Slower way
|
|
|
|
#self.append(textwrap.dedent("""\
|
|
|
|
# function monitor () {
|
|
|
|
# mysql -B -e "
|
|
|
|
# SELECT IFNULL(sum(data_length + index_length), 0) 'Size'
|
|
|
|
# FROM information_schema.TABLES
|
|
|
|
# WHERE table_schema = '$1';
|
|
|
|
# " | tail -n 1
|
|
|
|
# }"""))
|
2014-07-16 15:20:16 +00:00
|
|
|
|
2014-11-18 13:59:21 +00:00
|
|
|
def monitor(self, db):
|
|
|
|
if db.type != db.MYSQL:
|
|
|
|
return
|
|
|
|
context = self.get_context(db)
|
2016-05-27 09:54:46 +00:00
|
|
|
self.append('echo %(db_id)s $(monitor_%(db_type)s "%(db_dirname)s")' % context)
|
2014-07-16 15:20:16 +00:00
|
|
|
|
|
|
|
def get_context(self, db):
|
2015-04-05 18:02:36 +00:00
|
|
|
context = {
|
2014-07-16 15:20:16 +00:00
|
|
|
'db_name': db.name,
|
2015-05-19 13:27:04 +00:00
|
|
|
'db_dirname': db.name.replace('-', '@003f'),
|
2014-07-16 15:20:16 +00:00
|
|
|
'db_id': db.pk,
|
2016-05-27 09:54:46 +00:00
|
|
|
'db_type': db.type,
|
2014-07-16 15:20:16 +00:00
|
|
|
}
|
2015-04-05 18:02:36 +00:00
|
|
|
return replace(replace(context, "'", '"'), ';', '')
|