Merge pull request #830 from fvanboven/module-2111-replication

(MODULES-2111) Add the system database to user related actions.
This commit is contained in:
JT (Jonny) 2016-05-10 11:30:28 +01:00
commit 3e3cd55e04
4 changed files with 35 additions and 25 deletions

View file

@ -60,6 +60,15 @@ class Puppet::Provider::Mysql < Puppet::Provider
mysql([defaults_file, '-NBe', "SELECT CONCAT(User, '@',Host) AS User FROM mysql.user"].compact).split("\n")
end
# Optional parameter to run a statement on the MySQL system database.
def self.system_database
'--database=mysql'
end
def system_database
self.class.system_database
end
# Take root@localhost and munge it to 'root'@'localhost'
def self.cmd_user(user)
"'#{user.sub('@', "'@'")}'"

View file

@ -81,7 +81,7 @@ Puppet::Type.type(:mysql_grant).provide(:mysql, :parent => Puppet::Provider::Mys
query << " ON #{table_string}"
query << " TO #{user_string}"
query << self.class.cmd_options(options) unless options.nil?
mysql([defaults_file, '-e', query].compact)
mysql([defaults_file, system_database, '-e', query].compact)
end
def create
@ -107,10 +107,10 @@ Puppet::Type.type(:mysql_grant).provide(:mysql, :parent => Puppet::Provider::Mys
# exist to be executed successfully
if revoke_privileges.include? 'ALL'
query = "REVOKE GRANT OPTION ON #{table_string} FROM #{user_string}"
mysql([defaults_file, '-e', query].compact)
mysql([defaults_file, system_database, '-e', query].compact)
end
query = "REVOKE #{priv_string} ON #{table_string} FROM #{user_string}"
mysql([defaults_file, '-e', query].compact)
mysql([defaults_file, system_database, '-e', query].compact)
end
def destroy

View file

@ -61,18 +61,18 @@ Puppet::Type.type(:mysql_user).provide(:mysql, :parent => Puppet::Provider::Mysq
# This is also required if you want to specify a authentication plugin
if !plugin.nil?
if plugin == 'sha256_password' and !password_hash.nil?
mysql([defaults_file, '-e', "CREATE USER '#{merged_name}' IDENTIFIED WITH '#{plugin}' AS '#{password_hash}'"].compact)
mysql([defaults_file, system_database, '-e', "CREATE USER '#{merged_name}' IDENTIFIED WITH '#{plugin}' AS '#{password_hash}'"].compact)
else
mysql([defaults_file, '-e', "CREATE USER '#{merged_name}' IDENTIFIED WITH '#{plugin}'"].compact)
mysql([defaults_file, system_database, '-e', "CREATE USER '#{merged_name}' IDENTIFIED WITH '#{plugin}'"].compact)
end
@property_hash[:ensure] = :present
@property_hash[:plugin] = plugin
else
mysql([defaults_file, '-e', "CREATE USER '#{merged_name}' IDENTIFIED BY PASSWORD '#{password_hash}'"].compact)
mysql([defaults_file, system_database, '-e', "CREATE USER '#{merged_name}' IDENTIFIED BY PASSWORD '#{password_hash}'"].compact)
@property_hash[:ensure] = :present
@property_hash[:password_hash] = password_hash
end
mysql([defaults_file, '-e', "GRANT USAGE ON *.* TO '#{merged_name}' WITH MAX_USER_CONNECTIONS #{max_user_connections} MAX_CONNECTIONS_PER_HOUR #{max_connections_per_hour} MAX_QUERIES_PER_HOUR #{max_queries_per_hour} MAX_UPDATES_PER_HOUR #{max_updates_per_hour}"].compact)
mysql([defaults_file, system_database, '-e', "GRANT USAGE ON *.* TO '#{merged_name}' WITH MAX_USER_CONNECTIONS #{max_user_connections} MAX_CONNECTIONS_PER_HOUR #{max_connections_per_hour} MAX_QUERIES_PER_HOUR #{max_queries_per_hour} MAX_UPDATES_PER_HOUR #{max_updates_per_hour}"].compact)
@property_hash[:max_user_connections] = max_user_connections
@property_hash[:max_connections_per_hour] = max_connections_per_hour
@property_hash[:max_queries_per_hour] = max_queries_per_hour
@ -83,7 +83,7 @@ Puppet::Type.type(:mysql_user).provide(:mysql, :parent => Puppet::Provider::Mysq
def destroy
merged_name = @resource[:name].sub('@', "'@'")
mysql([defaults_file, '-e', "DROP USER '#{merged_name}'"].compact)
mysql([defaults_file, system_database, '-e', "DROP USER '#{merged_name}'"].compact)
@property_hash.clear
exists? ? (return false) : (return true)
@ -106,18 +106,18 @@ Puppet::Type.type(:mysql_user).provide(:mysql, :parent => Puppet::Provider::Mysq
# We have a fact for the mysql version ...
if mysqld_version.nil?
# default ... if mysqld_version does not work
mysql([defaults_file, '-e', "SET PASSWORD FOR #{merged_name} = '#{string}'"].compact)
mysql([defaults_file, system_database, '-e', "SET PASSWORD FOR #{merged_name} = '#{string}'"].compact)
else
# Version >= 5.7.6 (many password related changes)
if (mysqld_type == "mysql" or mysqld_type == "percona") and Puppet::Util::Package.versioncmp(mysqld_version, '5.7.6') >= 0
if string.match(/^\*/)
mysql([defaults_file, '-e', "ALTER USER #{merged_name} IDENTIFIED WITH mysql_native_password AS '#{string}'"].compact)
mysql([defaults_file, system_database, '-e', "ALTER USER #{merged_name} IDENTIFIED WITH mysql_native_password AS '#{string}'"].compact)
else
raise ArgumentError, "Only mysql_native_password (*ABCD...XXX) hashes are supported"
end
else
# older versions
mysql([defaults_file, '-e', "SET PASSWORD FOR #{merged_name} = '#{string}'"].compact)
mysql([defaults_file, system_database, '-e', "SET PASSWORD FOR #{merged_name} = '#{string}'"].compact)
end
end
@ -126,28 +126,28 @@ Puppet::Type.type(:mysql_user).provide(:mysql, :parent => Puppet::Provider::Mysq
def max_user_connections=(int)
merged_name = self.class.cmd_user(@resource[:name])
mysql([defaults_file, '-e', "GRANT USAGE ON *.* TO #{merged_name} WITH MAX_USER_CONNECTIONS #{int}"].compact).chomp
mysql([defaults_file, system_database, '-e', "GRANT USAGE ON *.* TO #{merged_name} WITH MAX_USER_CONNECTIONS #{int}"].compact).chomp
max_user_connections == int ? (return true) : (return false)
end
def max_connections_per_hour=(int)
merged_name = self.class.cmd_user(@resource[:name])
mysql([defaults_file, '-e', "GRANT USAGE ON *.* TO #{merged_name} WITH MAX_CONNECTIONS_PER_HOUR #{int}"].compact).chomp
mysql([defaults_file, system_database, '-e', "GRANT USAGE ON *.* TO #{merged_name} WITH MAX_CONNECTIONS_PER_HOUR #{int}"].compact).chomp
max_connections_per_hour == int ? (return true) : (return false)
end
def max_queries_per_hour=(int)
merged_name = self.class.cmd_user(@resource[:name])
mysql([defaults_file, '-e', "GRANT USAGE ON *.* TO #{merged_name} WITH MAX_QUERIES_PER_HOUR #{int}"].compact).chomp
mysql([defaults_file, system_database, '-e', "GRANT USAGE ON *.* TO #{merged_name} WITH MAX_QUERIES_PER_HOUR #{int}"].compact).chomp
max_queries_per_hour == int ? (return true) : (return false)
end
def max_updates_per_hour=(int)
merged_name = self.class.cmd_user(@resource[:name])
mysql([defaults_file, '-e', "GRANT USAGE ON *.* TO #{merged_name} WITH MAX_UPDATES_PER_HOUR #{int}"].compact).chomp
mysql([defaults_file, system_database, '-e', "GRANT USAGE ON *.* TO #{merged_name} WITH MAX_UPDATES_PER_HOUR #{int}"].compact).chomp
max_updates_per_hour == int ? (return true) : (return false)
end

View file

@ -49,6 +49,7 @@ describe Puppet::Type.type(:mysql_user).provider(:mysql) do
}
let(:defaults_file) { '--defaults-extra-file=/root/.my.cnf' }
let(:system_database) { '--database=mysql' }
let(:newhash) { '*6C8989366EAF75BB670AD8EA7A7FC1176A95CEF5' }
let(:raw_users) do
@ -177,8 +178,8 @@ usvn_user@localhost
describe 'create' do
it 'makes a user' do
provider.expects(:mysql).with([defaults_file, '-e', "CREATE USER 'joe'@'localhost' IDENTIFIED BY PASSWORD '*6C8989366EAF75BB670AD8EA7A7FC1176A95CEF4'"])
provider.expects(:mysql).with([defaults_file, '-e', "GRANT USAGE ON *.* TO 'joe'@'localhost' WITH MAX_USER_CONNECTIONS 10 MAX_CONNECTIONS_PER_HOUR 10 MAX_QUERIES_PER_HOUR 10 MAX_UPDATES_PER_HOUR 10"])
provider.expects(:mysql).with([defaults_file, system_database, '-e', "CREATE USER 'joe'@'localhost' IDENTIFIED BY PASSWORD '*6C8989366EAF75BB670AD8EA7A7FC1176A95CEF4'"])
provider.expects(:mysql).with([defaults_file, system_database, '-e', "GRANT USAGE ON *.* TO 'joe'@'localhost' WITH MAX_USER_CONNECTIONS 10 MAX_CONNECTIONS_PER_HOUR 10 MAX_QUERIES_PER_HOUR 10 MAX_UPDATES_PER_HOUR 10"])
provider.expects(:exists?).returns(true)
expect(provider.create).to be_truthy
end
@ -186,7 +187,7 @@ usvn_user@localhost
describe 'destroy' do
it 'removes a user if present' do
provider.expects(:mysql).with([defaults_file, '-e', "DROP USER 'joe'@'localhost'"])
provider.expects(:mysql).with([defaults_file, system_database, '-e', "DROP USER 'joe'@'localhost'"])
provider.expects(:exists?).returns(false)
expect(provider.destroy).to be_truthy
end
@ -242,42 +243,42 @@ usvn_user@localhost
describe 'password_hash=' do
it 'changes the hash mysql 5.5' do
provider.class.instance_variable_set(:@mysqld_version_string, mysql_version_string_hash['mysql-5.5'][:string])
provider.expects(:mysql).with([defaults_file, '-e', "SET PASSWORD FOR 'joe'@'localhost' = '*6C8989366EAF75BB670AD8EA7A7FC1176A95CEF5'"]).returns('0')
provider.expects(:mysql).with([defaults_file, system_database, '-e', "SET PASSWORD FOR 'joe'@'localhost' = '*6C8989366EAF75BB670AD8EA7A7FC1176A95CEF5'"]).returns('0')
provider.expects(:password_hash).returns('*6C8989366EAF75BB670AD8EA7A7FC1176A95CEF5')
provider.password_hash=('*6C8989366EAF75BB670AD8EA7A7FC1176A95CEF5')
end
it 'changes the hash mysql 5.6' do
provider.class.instance_variable_set(:@mysqld_version_string, mysql_version_string_hash['mysql-5.6'][:string])
provider.expects(:mysql).with([defaults_file, '-e', "SET PASSWORD FOR 'joe'@'localhost' = '*6C8989366EAF75BB670AD8EA7A7FC1176A95CEF5'"]).returns('0')
provider.expects(:mysql).with([defaults_file, system_database, '-e', "SET PASSWORD FOR 'joe'@'localhost' = '*6C8989366EAF75BB670AD8EA7A7FC1176A95CEF5'"]).returns('0')
provider.expects(:password_hash).returns('*6C8989366EAF75BB670AD8EA7A7FC1176A95CEF5')
provider.password_hash=('*6C8989366EAF75BB670AD8EA7A7FC1176A95CEF5')
end
it 'changes the hash mysql < 5.7.6' do
provider.class.instance_variable_set(:@mysqld_version_string, mysql_version_string_hash['mysql-5.7.1'][:string])
provider.expects(:mysql).with([defaults_file, '-e', "SET PASSWORD FOR 'joe'@'localhost' = '*6C8989366EAF75BB670AD8EA7A7FC1176A95CEF5'"]).returns('0')
provider.expects(:mysql).with([defaults_file, system_database, '-e', "SET PASSWORD FOR 'joe'@'localhost' = '*6C8989366EAF75BB670AD8EA7A7FC1176A95CEF5'"]).returns('0')
provider.expects(:password_hash).returns('*6C8989366EAF75BB670AD8EA7A7FC1176A95CEF5')
provider.password_hash=('*6C8989366EAF75BB670AD8EA7A7FC1176A95CEF5')
end
it 'changes the hash MySQL >= 5.7.6' do
provider.class.instance_variable_set(:@mysqld_version_string, mysql_version_string_hash['mysql-5.7.6'][:string])
provider.expects(:mysql).with([defaults_file, '-e', "ALTER USER 'joe'@'localhost' IDENTIFIED WITH mysql_native_password AS '*6C8989366EAF75BB670AD8EA7A7FC1176A95CEF5'"]).returns('0')
provider.expects(:mysql).with([defaults_file, system_database, '-e', "ALTER USER 'joe'@'localhost' IDENTIFIED WITH mysql_native_password AS '*6C8989366EAF75BB670AD8EA7A7FC1176A95CEF5'"]).returns('0')
provider.expects(:password_hash).returns('*6C8989366EAF75BB670AD8EA7A7FC1176A95CEF5')
provider.password_hash=('*6C8989366EAF75BB670AD8EA7A7FC1176A95CEF5')
end
it 'changes the hash mariadb-10.0' do
provider.class.instance_variable_set(:@mysqld_version_string, mysql_version_string_hash['mariadb-10.0'][:string])
provider.expects(:mysql).with([defaults_file, '-e', "SET PASSWORD FOR 'joe'@'localhost' = '*6C8989366EAF75BB670AD8EA7A7FC1176A95CEF5'"]).returns('0')
provider.expects(:mysql).with([defaults_file, system_database, '-e', "SET PASSWORD FOR 'joe'@'localhost' = '*6C8989366EAF75BB670AD8EA7A7FC1176A95CEF5'"]).returns('0')
provider.expects(:password_hash).returns('*6C8989366EAF75BB670AD8EA7A7FC1176A95CEF5')
provider.password_hash=('*6C8989366EAF75BB670AD8EA7A7FC1176A95CEF5')
end
it 'changes the hash percona-5.5' do
provider.class.instance_variable_set(:@mysqld_version_string, mysql_version_string_hash['percona-5.5'][:string])
provider.expects(:mysql).with([defaults_file, '-e', "SET PASSWORD FOR 'joe'@'localhost' = '*6C8989366EAF75BB670AD8EA7A7FC1176A95CEF5'"]).returns('0')
provider.expects(:mysql).with([defaults_file, system_database, '-e', "SET PASSWORD FOR 'joe'@'localhost' = '*6C8989366EAF75BB670AD8EA7A7FC1176A95CEF5'"]).returns('0')
provider.expects(:password_hash).returns('*6C8989366EAF75BB670AD8EA7A7FC1176A95CEF5')
provider.password_hash=('*6C8989366EAF75BB670AD8EA7A7FC1176A95CEF5')
@ -295,7 +296,7 @@ usvn_user@localhost
describe "#{property}=" do
it "changes #{property}" do
provider.expects(:mysql).with([defaults_file, '-e', "GRANT USAGE ON *.* TO 'joe'@'localhost' WITH #{property.upcase} 42"]).returns('0')
provider.expects(:mysql).with([defaults_file, system_database, '-e', "GRANT USAGE ON *.* TO 'joe'@'localhost' WITH #{property.upcase} 42"]).returns('0')
provider.expects(property.to_sym).returns('42')
provider.send("#{property}=".to_sym, '42')
end