Hi all, last night I wrote some of the worst code I have written in a while. I am literally proud of the amount of shame I feel for messing with code this badly. Naturally, waking up on Monday morning the bad code hangover is severe, but I don't quite see how this could be improved. That's where you boys and girls come in (hopefully ;) ).
What I want: pass a normal MySQL style string of mysql permissions and check for each of those and grant it if needed. The code I have now works, behold.. # Grant a mysql user permissions to a database # define mariadb::user::dummyloop($dbname, $grantoption, $isgrantable, $username, $pw, $real_admin_pass, $dbhost, $host_to_grant){ $grant_ = regsubst($name, '___', '', 'G') $grant_parts = split($grant_, '__') $grant = $grant_parts[3] if ($dbname == '*') { $real_dbname = "*.*" $privilege_check_query = "select count(*) from information_schema.USER_PRIVILEGES where GRANTEE=\\\"'${username}'@'${host_to_grant}'\\\" and PRIVILEGE_TYPE=\\\"${grant}\\\" and IS_GRANTABLE=\\\"${isgrantable}\\\"" } else { $real_dbname = "`${dbname}`.*" $privilege_check_query = "select count(*) from information_schema.SCHEMA_PRIVILEGES where TABLE_SCHEMA=\\\"'${dbname}'\\\" GRANTEE=\\\"'${username}'@'${host_to_grant}'\\\" and PRIVILEGE_TYPE=\\\"${grant}\\\" and IS_GRANTABLE=\\\"${isgrantable}\\\"" } exec { "create-grant-${name}-${username}-${host_to_grant}-${dbhost}": command => "/usr/bin/mysql -h${dbhost} -u${mariadb::params::admin_user} ${real_admin_pass} -e 'grant ${grant} on ${real_dbname} to `${username}`@`${host_to_grant}` identified by \"${pw}\" ${grantoption}'", path => "/bin:/usr/bin", onlyif => "[ `/usr/bin/mysql -h${dbhost} -u${mariadb::params::admin_user} ${real_admin_pass} -BN -e \"${privilege_check_query}\"` -eq 0 ]", require => Package[$mariadb::params::packagename_client] } } # Usage: mariadb::user { "dbname": "username" } define mariadb::user ($username, $pw, $dbname, $grants = 'all privileges', $host_to_grant = '%', $dbhost = 'localhost', $withgrants = false) { include mariadb::params if $withgrants { $grantoption = ' with grant option' $isgrantable = 'YES' } else { $grantoption = '' $isgrantable = 'NO' } if ($mariadb::params::admin_pass == '') { $real_admin_pass = '' } else { $real_admin_pass = "-p\"${mariadb::params::admin_pass}\"" } # This is some very nasty puppet stunts to make it possible to run through a string of grants # First we surround every grant by triple underscores, then prefix it with host, databasename and username so the $name variable of the dummyloop stays unique #replace all spaces by underscores #$grants = 'INSERT, DELETE' $grants_ = regsubst($grants, '\s*,\s*', "___,___${dbhost}__${dbname}__${username}__", 'G') #$grants_ = 'INSERT__,__DELETE' $grants__ = "___${dbhost}__${dbname}__${username}__${grants_}___" #$grants__ = "__localhost_zabbix_zabbixuser_INSERT__,__DELETE__ # split the grants by comma into an array $grants_array = split($grants__,',') #$grants_array = # call dummy loop with the array in order to check/create all desired grants mariadb::user::dummyloop{ $grants_array: dbname => $dbname, grantoption => $grantoption, isgrantable => $isgrantable, username => $username, pw => $pw, real_admin_pass => $real_admin_pass, dbhost => $dbhost, host_to_grant => $host_to_grant } } Better ways are more then welcome (or a decent implementation to loop through arrays in puppet ;) ) kind regards, -- Walter Heck -- follow @walterheck on twitter to see what I'm up to! -- Check out my new startup: Server Monitoring as a Service @ http://tribily.com Follow @tribily on Twitter and/or 'Like' our Facebook page at http://www.facebook.com/tribily -- You received this message because you are subscribed to the Google Groups "Puppet Users" group. To post to this group, send email to puppet-users@googlegroups.com. To unsubscribe from this group, send email to puppet-users+unsubscr...@googlegroups.com. For more options, visit this group at http://groups.google.com/group/puppet-users?hl=en.