diff --git a/elements/mysql/element-deps b/elements/mysql/element-deps new file mode 100644 index 000000000..e375b247c --- /dev/null +++ b/elements/mysql/element-deps @@ -0,0 +1,2 @@ +os-config-applier +os-refresh-config diff --git a/elements/mysql/install.d/10-mysql b/elements/mysql/install.d/10-mysql index 2593ff36d..ef83e3302 100755 --- a/elements/mysql/install.d/10-mysql +++ b/elements/mysql/install.d/10-mysql @@ -8,4 +8,4 @@ set -o xtrace install -D -m 0644 -o root -g root $(dirname $0)/my.cnf /etc/mysql/my.cnf install $(dirname $0)/mysql-set-server-id.upstart /etc/init/mysql-set-server-id.conf -install-packages sysstat mytop percona-toolkit mysql-server-5.5 mysql-client-5.5 +install-packages sysstat mytop percona-toolkit mysql-server-5.5 mysql-client-5.5 python-mysqldb diff --git a/elements/mysql/os-config-applier/etc/mysql/dbusers.json b/elements/mysql/os-config-applier/etc/mysql/dbusers.json new file mode 100644 index 000000000..7b4aafe92 --- /dev/null +++ b/elements/mysql/os-config-applier/etc/mysql/dbusers.json @@ -0,0 +1 @@ +{{mysql.create-users}} diff --git a/elements/mysql/os-config-applier/etc/mysql/static-dbusers.json b/elements/mysql/os-config-applier/etc/mysql/static-dbusers.json new file mode 100644 index 000000000..2ed3010aa --- /dev/null +++ b/elements/mysql/os-config-applier/etc/mysql/static-dbusers.json @@ -0,0 +1 @@ +[{"username": "root"}, {"username": "debian-sys-maint"}] diff --git a/elements/mysql/os-refresh-config/post-configure.d/50-mysql-users b/elements/mysql/os-refresh-config/post-configure.d/50-mysql-users new file mode 100755 index 000000000..8486d65b6 --- /dev/null +++ b/elements/mysql/os-refresh-config/post-configure.d/50-mysql-users @@ -0,0 +1,87 @@ +#!/usr/bin/python +# +# Assert users that came from metadata config +# +# Copyright 2013 Hewlett-Packard Development Company, L.P. +# All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. +# + +import subprocess +import MySQLdb +import logging +import argparse +import os +import json +from base64 import b64encode + +logging.basicConfig() +logger = logging.getLogger('mysql-users') + +# Root should have a my.cnf setup +conn = MySQLdb.Connect(read_default_file=os.path.expanduser('~/.my.cnf')) +cursor = conn.cursor() +rows = cursor.execute("SELECT DISTINCT User FROM mysql.user WHERE user != ''") +existing = set([x[0] for x in cursor.fetchmany(size=rows)]) +cursor.close() +should_exist = set() +by_user = {} + + +def load_userfile(path): + global should_exist + global by_user + if os.path.exists(path): + with open(path) as dbusers_file: + db_users = json.load(dbusers_file) + if not isinstance(db_users, list): + raise ValueError('%s must be a list' % (path)) + for dbvalues in db_users: + username = dbvalues['username'] + should_exist.add(username) + by_user[username] = dbvalues + +parser = argparse.ArgumentParser() +parser.add_argument('--noop', '-n', default=False, action='store_true') + +opts = parser.parse_args() + +load_userfile('/etc/mysql/static-dbusers.json') +load_userfile('/etc/mysql/dbusers.json') + +to_delete = existing - should_exist +to_create = should_exist - existing + +for createuser in to_create: + dbvalue = by_user[createuser] + with open('/dev/urandom', 'rb') as urandom: + password = b64encode(urandom.read(30)) + cmd = "GRANT ALL PRIVILEGES ON `%s`.* TO `%s`@'%%' IDENTIFIED BY '%s'" % ( + dbvalue['database'], dbvalue['username'], password) + if opts.noop: + print "%s" % (cmd) + else: + cursor = conn.cursor() + cursor.execute(cmd) + cursor.close() + # Inform Heat of new password for this user + cmd = ['/opt/aws/bin/cfn-signal', '-i', dbvalue['username'], + '-s', 'true', '--data', password, dbvalue['userhandle']] + if opts.noop: + print cmd + else: + subprocess.check_call(cmd) + +if to_delete: + logger.warn('The following users are not accounted for: %s' % to_delete)