Create users in mysql server based on metadata
Enable templates to specify a list of users that need passwords assigned in Metadata. These passwords are then communicated back to the template via an optional wait condition handle using cfn-signal. Change-Id: Iaaf4d4a9d0d757b7d44ea39e77eed3c55ffffd88
This commit is contained in:
		
				
					committed by
					
						
						Gerrit Code Review
					
				
			
			
				
	
			
			
			
						parent
						
							6bf07b12d3
						
					
				
				
					commit
					ff7eac3c65
				
			
							
								
								
									
										2
									
								
								elements/mysql/element-deps
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										2
									
								
								elements/mysql/element-deps
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,2 @@
 | 
			
		||||
os-config-applier
 | 
			
		||||
os-refresh-config
 | 
			
		||||
@@ -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
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										1
									
								
								elements/mysql/os-config-applier/etc/mysql/dbusers.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								elements/mysql/os-config-applier/etc/mysql/dbusers.json
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1 @@
 | 
			
		||||
{{mysql.create-users}}
 | 
			
		||||
@@ -0,0 +1 @@
 | 
			
		||||
[{"username": "root"}, {"username": "debian-sys-maint"}]
 | 
			
		||||
							
								
								
									
										87
									
								
								elements/mysql/os-refresh-config/post-configure.d/50-mysql-users
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										87
									
								
								elements/mysql/os-refresh-config/post-configure.d/50-mysql-users
									
									
									
									
									
										Executable file
									
								
							@@ -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)
 | 
			
		||||
		Reference in New Issue
	
	Block a user