diff --git a/lib/puppet/provider/database_user/mysql.rb b/lib/puppet/provider/database_user/mysql.rb index 3eee597..a4f0942 100644 --- a/lib/puppet/provider/database_user/mysql.rb +++ b/lib/puppet/provider/database_user/mysql.rb @@ -4,8 +4,8 @@ Puppet::Type.type(:database_user).provide(:mysql) do defaultfor :kernel => 'Linux' - optional_commands :mysql => 'mysql' - optional_commands :mysqladmin => 'mysqladmin' + commands :mysql => 'mysql' + commands :mysqladmin => 'mysqladmin' def self.instances users = mysql([defaults_file, "mysql", '-BNe' "select concat(User, '@',Host) as User from mysql.user"].compact).split("\n") @@ -15,19 +15,28 @@ Puppet::Type.type(:database_user).provide(:mysql) do end def create - mysql([defaults_file, "mysql", "-e", "create user '%s' identified by PASSWORD '%s'" % [ @resource[:name].sub("@", "'@'"), @resource.value(:password_hash) ]].compact) + merged_name = @resource[:name].sub("@", "'@'") + password_hash = @resource.value(:password_hash) + mysql([defaults_file, "mysql", "-e", "create user '#{merged_name}' identified by PASSWORD '#{password_hash}'"].compact) + + exists? ? (return true) : (return false) end def destroy - mysql([defaults_file, "mysql", "-e", "drop user '%s'" % @resource.value(:name).sub("@", "'@'") ].compact) + merged_name = @resource[:name].sub("@", "'@'") + mysql([defaults_file, "mysql", "-e", "drop user '#{merged_name}'"].compact) + + exists? ? (return false) : (return true) end def password_hash - mysql([defaults_file, "mysql", "-NBe", "select password from mysql.user where CONCAT(user, '@', host) = '%s'" % @resource.value(:name)].compact).chomp + mysql([defaults_file, "mysql", "-NBe", "select password from mysql.user where CONCAT(user, '@', host) = '#{@resource[:name]}'"].compact).chomp end def password_hash=(string) mysql([defaults_file, "mysql", "-e", "SET PASSWORD FOR '%s' = '%s'" % [ @resource[:name].sub("@", "'@'"), string ] ].compact) + + password_hash == string ? (return true) : (return false) end def exists? diff --git a/spec/unit/puppet/provider/database_grant/mysql_spec.rb b/spec/unit/puppet/provider/database_grant/mysql_spec.rb index 9a09d42..353a1ec 100644 --- a/spec/unit/puppet/provider/database_grant/mysql_spec.rb +++ b/spec/unit/puppet/provider/database_grant/mysql_spec.rb @@ -17,7 +17,7 @@ describe provider_class do File.stubs(:file?).with("#{root_home}/.my.cnf").returns(true) end - it 'should query privilegess from the database' do + it 'should query privileges from the database' do provider_class.expects(:mysql) .with(["--defaults-file=#{root_home}/.my.cnf", 'mysql', '-Be', 'describe user']).returns <<-EOT Field Type Null Key Default Extra Host char(60) NO PRI @@ -40,7 +40,7 @@ EOT provider_class.db_privs.should == [ 'Select_priv', 'Insert_priv', 'Update_priv' ] end - it 'should query set priviliges' do + it 'should query set privileges' do provider_class.expects(:mysql).with(["--defaults-file=#{root_home}/.my.cnf", 'mysql', '-Be', "select * from mysql.user where user='user' and host='host'"]).returns <<-EOT Host User Password Select_priv Insert_priv Update_priv host user Y N Y @@ -48,7 +48,7 @@ EOT @provider.privileges.should == [ 'Select_priv', 'Update_priv' ] end - it 'should recognize when all priviliges are set' do + it 'should recognize when all privileges are set' do provider_class.expects(:mysql).with(["--defaults-file=#{root_home}/.my.cnf", 'mysql', '-Be', "select * from mysql.user where user='user' and host='host'"]).returns <<-EOT Host User Password Select_priv Insert_priv Update_priv host user Y Y Y diff --git a/spec/unit/puppet/provider/database_user/mysql_spec.rb b/spec/unit/puppet/provider/database_user/mysql_spec.rb new file mode 100644 index 0000000..d022fc4 --- /dev/null +++ b/spec/unit/puppet/provider/database_user/mysql_spec.rb @@ -0,0 +1,100 @@ +require 'spec_helper' + +provider_class = Puppet::Type.type(:database_user).provider(:mysql) + +describe provider_class do + subject { provider_class } + + let(:root_home) { '/root' } + let(:defaults_file) { '--defaults-file=/root/.my.cnf' } + let(:newhash) { '*6C8989366EAF75BB670AD8EA7A7FC1176A95CEF5' } + + let(:raw_users) do + <<-SQL_OUTPUT +root@127.0.0.1 +root@::1 +@localhost +debian-sys-maint@localhost +root@localhost +usvn_user@localhost +@vagrant-ubuntu-raring-64 + SQL_OUTPUT + end + + let(:parsed_users) { ['root@127.0.0.1', 'root@::1', 'debian-sys-maint@localhost', 'root@localhost', 'usvn_user@localhost'] } + + before :each do + # password hash = mypass + @resource = Puppet::Type::Database_user.new( + { :password_hash => '*6C8989366EAF75BB670AD8EA7A7FC1176A95CEF4', :name => 'joe@localhost' } + ) + @provider = provider_class.new(@resource) + Facter.stubs(:value).with(:root_home).returns(root_home) + Puppet::Util.stubs(:which).with("mysql").returns("/usr/bin/mysql") + subject.stubs(:which).with("mysql").returns("/usr/bin/mysql") + subject.stubs(:defaults_file).returns('--defaults-file=/root/.my.cnf') + end + + describe 'self.instances' do + it 'returns an array of users' do + subject.stubs(:mysql).with([defaults_file, 'mysql', "-BNeselect concat(User, '@',Host) as User from mysql.user"]).returns(raw_users) + + usernames = subject.instances.collect {|x| x.name } + parsed_users.should match_array(usernames) + end + end + + describe 'create' do + it 'makes a user' do + subject.expects(:mysql).with([defaults_file, 'mysql', '-e', "create user 'joe'@'localhost' identified by PASSWORD '*6C8989366EAF75BB670AD8EA7A7FC1176A95CEF4'"]) + @provider.expects(:exists?).returns(true) + @provider.create.should be_true + end + end + + describe 'destroy' do + it 'removes a user if present' do + subject.expects(:mysql).with([defaults_file, 'mysql', '-e', "drop user 'joe'@'localhost'"]) + @provider.expects(:exists?).returns(false) + @provider.destroy.should be_true + end + end + + describe 'password_hash' do + it 'returns a hash' do + subject.expects(:mysql).with([defaults_file, 'mysql', '-NBe', "select password from mysql.user where CONCAT(user, '@', host) = 'joe@localhost'"]).returns('*6C8989366EAF75BB670AD8EA7A7FC1176A95CEF4') + @provider.password_hash.should == '*6C8989366EAF75BB670AD8EA7A7FC1176A95CEF4' + end + end + + describe 'password_hash=' do + it 'changes the hash' do + subject.expects(:mysql).with([defaults_file, 'mysql', '-e', "SET PASSWORD FOR 'joe'@'localhost' = '*6C8989366EAF75BB670AD8EA7A7FC1176A95CEF5'"]).returns('0') + + @provider.expects(:password_hash).returns('*6C8989366EAF75BB670AD8EA7A7FC1176A95CEF5') + @provider.password_hash=('*6C8989366EAF75BB670AD8EA7A7FC1176A95CEF5') + end + end + + describe 'exists?' do + it 'checks if user exists' do + subject.expects(:mysql).with([defaults_file, 'mysql', '-NBe', "select '1' from mysql.user where CONCAT(user, '@', host) = 'joe@localhost'"]).returns('1') + @provider.exists?.should be_true + end + end + + describe 'flush' do + it 'removes cached privileges' do + subject.expects(:mysqladmin).with([defaults_file, 'flush-privileges']) + @provider.flush + end + end + + describe 'self.defaults_file' do + it 'sets --defaults-file' do + File.stubs(:file?).with('#{root_home}/.my.cnf').returns(true) + @provider.defaults_file.should == '--defaults-file=/root/.my.cnf' + end + end + +end