diff --git a/lib/puppet/provider/database/mysql.rb b/lib/puppet/provider/database/mysql.rb deleted file mode 100644 index ace742967..000000000 --- a/lib/puppet/provider/database/mysql.rb +++ /dev/null @@ -1,41 +0,0 @@ -require File.expand_path(File.join(File.dirname(__FILE__), '..', 'mysql')) -Puppet::Type.type(:database).provide(:mysql, :parent => Puppet::Provider::Mysql) do - desc 'Manages MySQL database.' - - defaultfor :kernel => 'Linux' - - optional_commands :mysql => 'mysql' - optional_commands :mysqladmin => 'mysqladmin' - - def self.instances - mysql([defaults_file, '-NBe', 'show databases'].compact).split("\n").collect do |name| - new(:name => name) - end - end - - def create - mysql([defaults_file, '-NBe', "create database `#{@resource[:name]}` character set #{resource[:charset]}"].compact) - end - - def destroy - mysqladmin([defaults_file, '-f', 'drop', @resource[:name]].compact) - end - - def charset - mysql([defaults_file, '-NBe', "show create database `#{resource[:name]}`"].compact).match(/.*?(\S+)\s(?:COLLATE.*)?\*\//)[1] - end - - def charset=(value) - mysql([defaults_file, '-NBe', "alter database `#{resource[:name]}` CHARACTER SET #{value}"].compact) - end - - def exists? - begin - mysql([defaults_file, '-NBe', 'show databases'].compact).match(/^#{@resource[:name]}$/) - rescue => e - debug(e.message) - return nil - end - end - -end diff --git a/lib/puppet/provider/database_grant/mysql.rb b/lib/puppet/provider/database_grant/mysql.rb deleted file mode 100644 index eabc649c3..000000000 --- a/lib/puppet/provider/database_grant/mysql.rb +++ /dev/null @@ -1,199 +0,0 @@ -# A grant is either global or per-db. This can be distinguished by the syntax -# of the name: -# user@host => global -# user@host/db => per-db - -require File.expand_path(File.join(File.dirname(__FILE__), '..', 'mysql')) -Puppet::Type.type(:database_grant).provide(:mysql, :parent => Puppet::Provider::Mysql) do - - desc 'Uses mysql as database.' - - defaultfor :kernel => 'Linux' - - optional_commands :mysql => 'mysql' - optional_commands :mysqladmin => 'mysqladmin' - - def self.prefetch(resources) - @user_privs = query_user_privs - @db_privs = query_db_privs - end - - def self.user_privs - @user_privs || query_user_privs - end - - def self.db_privs - @db_privs || query_db_privs - end - - def user_privs - self.class.user_privs - end - - def db_privs - self.class.db_privs - end - - def self.query_user_privs - results = mysql([defaults_file, 'mysql', '-Be', 'describe user'].compact) - column_names = results.split(/\n/).map { |l| l.chomp.split(/\t/)[0] } - @user_privs = column_names.delete_if { |e| !( e =~/_priv$/) } - end - - def self.query_db_privs - results = mysql([defaults_file, 'mysql', '-Be', 'describe db'].compact) - column_names = results.split(/\n/).map { |l| l.chomp.split(/\t/)[0] } - @db_privs = column_names.delete_if { |e| !(e =~/_priv$/) } - end - - def mysql_flush - mysqladmin([defaults_file, 'flush-privileges'].compact) - end - - # this parses the - def split_name(string) - matches = /^([^@]*)@([^\/]*)(\/(.*))?$/.match(string).captures.compact - case matches.length - when 2 - { - :type => :user, - :user => matches[0], - :host => matches[1] - } - when 4 - { - :type => :db, - :user => matches[0], - :host => matches[1], - :db => matches[3] - } - end - end - - def create_row - unless @resource.should(:privileges).empty? - name = split_name(@resource[:name]) - case name[:type] - when :user - mysql([defaults_file, 'mysql', '-e', "INSERT INTO user (host, user) VALUES ('%s', '%s')" % [ - name[:host], name[:user], - ]].compact) - when :db - mysql([defaults_file, 'mysql', '-e', "INSERT INTO db (host, user, db) VALUES ('%s', '%s', '%s')" % [ - name[:host], name[:user], name[:db], - ]].compact) - end - mysql_flush - end - end - - def destroy - mysql([defaults_file, 'mysql', '-e', "REVOKE ALL ON '%s'.* FROM '%s@%s'" % [ @resource[:privileges], @resource[:database], @resource[:name], @resource[:host] ]].compact) - end - - def row_exists? - name = split_name(@resource[:name]) - fields = [:user, :host] - if name[:type] == :db - fields << :db - end - not mysql([defaults_file, 'mysql', '-NBe', "SELECT '1' FROM %s WHERE %s" % [ name[:type], fields.map do |f| "%s='%s'" % [f, name[f]] end.join(' AND ')]].compact).empty? - end - - def all_privs_set? - all_privs = case split_name(@resource[:name])[:type] - when :user - user_privs - when :db - db_privs - end - all_privs = all_privs.collect do |p| p.downcase end.sort.join('|') - privs = privileges.collect do |p| p.downcase end.sort.join('|') - - all_privs == privs - end - - def privileges - name = split_name(@resource[:name]) - privs = '' - - case name[:type] - when :user - privs = mysql([defaults_file, 'mysql', '-Be', "select * from mysql.user where user='%s' and host='%s'" % [ name[:user], name[:host] ]].compact) - when :db - privs = mysql([defaults_file, 'mysql', '-Be', "select * from mysql.db where user='%s' and host='%s' and db='%s'" % [ name[:user], name[:host], name[:db] ]].compact) - end - - if privs.match(/^$/) - privs = [] # no result, no privs - else - # returns a line with field names and a line with values, each tab-separated - privs = privs.split(/\n/).map! do |l| l.chomp.split(/\t/) end - # transpose the lines, so we have key/value pairs - privs = privs[0].zip(privs[1]) - privs = privs.select do |p| p[0].match(/_priv$/) and p[1] == 'Y' end - end - - privs.collect do |p| p[0] end - end - - def privileges=(privs) - unless row_exists? - create_row - end - - # puts "Setting privs: ", privs.join(", ") - name = split_name(@resource[:name]) - stmt = '' - where = '' - all_privs = [] - case name[:type] - when :user - stmt = 'update user set ' - where = " where user='%s' and host='%s'" % [ name[:user], name[:host] ] - all_privs = user_privs - when :db - stmt = 'update db set ' - where = " where user='%s' and host='%s' and db='%s'" % [ name[:user], name[:host], name[:db] ] - all_privs = db_privs - end - - if privs[0].downcase == 'all' - privs = all_privs - end - - # Downcase the requested priviliges for case-insensitive selection - # we don't map! here because the all_privs object has to remain in - # the same case the DB gave it to us in - privs = privs.map { |p| p.downcase } - - # puts "stmt:", stmt - set = all_privs.collect do |p| "%s = '%s'" % [p, privs.include?(p.downcase) ? 'Y' : 'N'] end.join(', ') - # puts "set:", set - stmt = stmt << set << where - - validate_privs privs, all_privs - mysql([defaults_file, 'mysql', '-Be', stmt].compact) - mysql_flush - end - - def validate_privs(set_privs, all_privs) - all_privs = all_privs.collect { |p| p.downcase } - set_privs = set_privs.collect { |p| p.downcase } - invalid_privs = Array.new - hints = Array.new - # Test each of the user provided privs to see if they exist in all_privs - set_privs.each do |priv| - invalid_privs << priv unless all_privs.include?(priv) - hints << "#{priv}_priv" if all_privs.include?("#{priv}_priv") - end - unless invalid_privs.empty? - # Print a decently helpful and gramatically correct error message - hints = "Did you mean '#{hints.join(',')}'?" unless hints.empty? - p = invalid_privs.size > 1 ? ['s', 'are not valid'] : ['', 'is not valid'] - detail = ["The privilege#{p[0]} '#{invalid_privs.join(',')}' #{p[1]}."] - fail [detail, hints].join(' ') - end - end - -end diff --git a/lib/puppet/provider/database_user/mysql.rb b/lib/puppet/provider/database_user/mysql.rb deleted file mode 100644 index 71e76d5c3..000000000 --- a/lib/puppet/provider/database_user/mysql.rb +++ /dev/null @@ -1,65 +0,0 @@ -require File.expand_path(File.join(File.dirname(__FILE__), '..', 'mysql')) -Puppet::Type.type(:database_user).provide(:mysql, :parent => Puppet::Provider::Mysql) do - - desc 'manage users for a mysql database.' - - defaultfor :kernel => 'Linux' - - 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") - users.select{ |user| user =~ /.+@/ }.collect do |name| - new(:name => name) - end - end - - def create - merged_name = self.class.cmd_user(@resource[:name]) - password_hash = @resource.value(:password_hash) - max_user_connections = @resource.value(:max_user_connections) || 0 - - mysql([defaults_file, 'mysql', '-e', "grant usage on *.* to #{merged_name} identified by PASSWORD - '#{password_hash}' with max_user_connections #{max_user_connections}"].compact) - - exists? ? (return true) : (return false) - end - - def destroy - merged_name = self.class.cmd_user(@resource[:name]) - 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) = '#{@resource[:name]}'"].compact).chomp - end - - def password_hash=(string) - mysql([defaults_file, 'mysql', '-e', "SET PASSWORD FOR #{self.class.cmd_user(@resource[:name])} = '#{string}'"].compact) - - password_hash == string ? (return true) : (return false) - end - - def max_user_connections - mysql([defaults_file, "mysql", "-NBe", "select max_user_connections from mysql.user where CONCAT(user, '@', host) = '#{@resource[:name]}'"].compact).chomp - end - - def max_user_connections=(int) - mysql([defaults_file, "mysql", "-e", "grant usage on *.* to %s with max_user_connections #{int}" % [ self.class.cmd_user(@resource[:name])] ].compact).chomp - - max_user_connections == int ? (return true) : (return false) - end - - def exists? - not mysql([defaults_file, 'mysql', '-NBe', "select '1' from mysql.user where CONCAT(user, '@', host) = '%s'" % @resource.value(:name)].compact).empty? - end - - def flush - @property_hash.clear - mysqladmin([defaults_file, 'flush-privileges'].compact) - end - -end diff --git a/lib/puppet/type/database.rb b/lib/puppet/type/database.rb deleted file mode 100644 index b02fb1099..000000000 --- a/lib/puppet/type/database.rb +++ /dev/null @@ -1,21 +0,0 @@ -# This has to be a separate type to enable collecting -Puppet::Type.newtype(:database) do - @doc = 'Manage databases.' - - ensurable - - newparam(:name, :namevar=>true) do - desc 'The name of the database.' - validate do |value| - Puppet.warning("database has been deprecated in favor of mysql_database.") - true - end - end - - newproperty(:charset) do - desc 'The characterset to use for a database' - defaultto :utf8 - newvalue(/^\S+$/) - end - -end diff --git a/lib/puppet/type/database_grant.rb b/lib/puppet/type/database_grant.rb deleted file mode 100644 index 7fdad8231..000000000 --- a/lib/puppet/type/database_grant.rb +++ /dev/null @@ -1,79 +0,0 @@ -# This has to be a separate type to enable collecting -Puppet::Type.newtype(:database_grant) do - @doc = "Manage a database user's rights." - #ensurable - - autorequire :database do - # puts "Starting db autoreq for %s" % self[:name] - reqs = [] - matches = self[:name].match(/^([^@]+)@([^\/]+)\/(.+)$/) - unless matches.nil? - reqs << matches[3] - end - # puts "Autoreq: '%s'" % reqs.join(" ") - reqs - end - - autorequire :database_user do - # puts "Starting user autoreq for %s" % self[:name] - reqs = [] - matches = self[:name].match(/^([^@]+)@([^\/]+).*$/) - unless matches.nil? - reqs << '%s@%s' % [ matches[1], matches[2] ] - end - # puts "Autoreq: '%s'" % reqs.join(" ") - reqs - end - - newparam(:name, :namevar=>true) do - desc 'The primary key: either user@host for global privilges or user@host/database for database specific privileges' - validate do |value| - Puppet.warning("database_grant has been deprecated in favor of mysql_grant.") - true - end - end - - newproperty(:privileges, :array_matching => :all) do - desc 'The privileges the user should have. The possible values are implementation dependent.' - - def should_to_s(newvalue = @should) - if newvalue - unless newvalue.is_a?(Array) - newvalue = [ newvalue ] - end - newvalue.collect do |v| v.downcase end.sort.join ', ' - else - nil - end - end - - def is_to_s(currentvalue = @is) - if currentvalue - unless currentvalue.is_a?(Array) - currentvalue = [ currentvalue ] - end - currentvalue.collect do |v| v.downcase end.sort.join ', ' - else - nil - end - end - - # use the sorted outputs for comparison - def insync?(is) - if defined? @should and @should - case self.should_to_s - when 'all' - self.provider.all_privs_set? - when self.is_to_s(is) - true - else - false - end - else - true - end - end - end - -end - diff --git a/lib/puppet/type/database_user.rb b/lib/puppet/type/database_user.rb deleted file mode 100644 index 24abc70d5..000000000 --- a/lib/puppet/type/database_user.rb +++ /dev/null @@ -1,36 +0,0 @@ -# This has to be a separate type to enable collecting -Puppet::Type.newtype(:database_user) do - @doc = 'Manage a database user. This includes management of users password as well as privileges' - - ensurable - - newparam(:name, :namevar=>true) do - desc "The name of the user. This uses the 'username@hostname' or username@hostname." - validate do |value| - Puppet.warning("database has been deprecated in favor of mysql_user.") - # https://dev.mysql.com/doc/refman/5.1/en/account-names.html - # Regex should problably be more like this: /^[`'"]?[^`'"]*[`'"]?@[`'"]?[\w%\.]+[`'"]?$/ - raise(ArgumentError, "Invalid database user #{value}") unless value =~ /[\w-]*@[\w%\.:]+/ - username = value.split('@')[0] - if username.size > 16 - raise ArgumentError, 'MySQL usernames are limited to a maximum of 16 characters' - end - end - - munge do |value| - user_part, host_part = value.split('@') - "#{user_part}@#{host_part.downcase}" - end - end - - newproperty(:password_hash) do - desc 'The password hash of the user. Use mysql_password() for creating such a hash.' - newvalue(/\w+/) - end - - newproperty(:max_user_connections) do - desc "Max concurrent connections for the user. 0 means no (or global) limit." - newvalue(/\d+/) - end - -end diff --git a/manifests/backup.pp b/manifests/backup.pp deleted file mode 100644 index 680a5744d..000000000 --- a/manifests/backup.pp +++ /dev/null @@ -1,31 +0,0 @@ -# Deprecated class -class mysql::backup ( - $backupuser, - $backuppassword, - $backupdir, - $backupcompress = true, - $backuprotate = 30, - $delete_before_dump = false, - $backupdatabases = [], - $file_per_database = false, - $ensure = 'present', - $time = ['23', '5'], -) { - - crit("This class has been deprecated and callers should directly call - mysql::server::backup now.") - - class { 'mysql::server::backup': - ensure => $ensure, - backupuser => $backupuser, - backuppassword => $backuppassword, - backupdir => $backupdir, - backupcompress => $backupcompress, - backuprotate => $backuprotate, - delete_before_dump => $delete_before_dump, - backupdatabases => $backupdatabases, - file_per_database => $file_per_database, - time => $time, - } - -} diff --git a/manifests/init.pp b/manifests/init.pp deleted file mode 100644 index eba5c2063..000000000 --- a/manifests/init.pp +++ /dev/null @@ -1,100 +0,0 @@ -# -class mysql( - $basedir = '', - $bind_address = '', - $client_package_ensure = '', - $client_package_name = '', - $config_file = '', - $config_template = '', - $datadir = '', - $default_engine = '', - $etc_root_password = '', - $log_error = '', - $manage_config_file = '', - $manage_service = '', - $max_allowed_packet = '', - $max_connections = '', - $old_root_password = '', - $package_ensure = '', - $php_package_name = '', - $pidfile = '', - $port = '', - $purge_conf_dir = '', - $restart = '', - $root_group = '', - $root_password = '', - $server_package_name = '', - $service_name = '', - $service_provider = '', - $socket = '', - $ssl = '', - $ssl_ca = '', - $ssl_cert = '', - $ssl_key = '', - $tmpdir = '', - $attempt_compatibility_mode = false, -) { - - if $attempt_compatibility_mode { - notify { "An attempt has been made below to automatically apply your custom - settings to mysql::server. Please verify this works in a safe test - environment.": } - - $override_options = { - 'client' => { - 'port' => $port, - 'socket' => $socket - }, - 'mysqld_safe' => { - 'log_error' => $log_error, - 'socket' => $socket, - }, - 'mysqld' => { - 'basedir' => $basedir, - 'bind_address' => $bind_address, - 'datadir' => $datadir, - 'log_error' => $log_error, - 'max_allowed_packet' => $max_allowed_packet, - 'max_connections' => $max_connections, - 'pid_file' => $pidfile, - 'port' => $port, - 'socket' => $socket, - 'ssl-ca' => $ssl_ca, - 'ssl-cert' => $ssl_cert, - 'ssl-key' => $ssl_key, - 'tmpdir' => $tmpdir, - }, - 'mysqldump' => { - 'max_allowed_packet' => $max_allowed_packet, - }, - 'config_file' => $config_file, - 'etc_root_password' => $etc_root_password, - 'manage_config_file' => $manage_config_file, - 'old_root_password' => $old_root_password, - 'purge_conf_dir' => $purge_conf_dir, - 'restart' => $restart, - 'root_group' => $root_group, - 'root_password' => $root_password, - 'service_name' => $service_name, - 'ssl' => $ssl - } - $filtered_options = mysql_strip_hash($override_options) - validate_hash($filtered_options) - notify { $filtered_options: } - class { 'mysql::server': - override_options => $filtered_options, - } - - } else { - fail("ERROR: This class has been deprecated and the functionality moved - into mysql::server. If you run mysql::server without correctly calling - mysql:: server with the new override_options hash syntax you will revert - your MySQL to the stock settings. Do not proceed without removing this - class and using mysql::server correctly. - - If you are brave you may set attempt_compatibility_mode in this class which - attempts to automap the previous settings to appropriate calls to - mysql::server") - } - -} diff --git a/metadata.json b/metadata.json index 0e9cfe536..bbf4246f3 100644 --- a/metadata.json +++ b/metadata.json @@ -1,6 +1,6 @@ { "name": "puppetlabs-mysql", - "version": "2.3.1", + "version": "3.0.0", "author": "Puppet Labs", "summary": "Mysql module", "license": "Apache 2.0", diff --git a/spec/unit/puppet/provider/database/mysql_spec.rb b/spec/unit/puppet/provider/database/mysql_spec.rb deleted file mode 100644 index e2557fc35..000000000 --- a/spec/unit/puppet/provider/database/mysql_spec.rb +++ /dev/null @@ -1,86 +0,0 @@ -require 'spec_helper' - -provider_class = Puppet::Type.type(:database).provider(:mysql) - -describe provider_class do - subject { provider_class } - - let(:root_home) { '/root' } - let(:defaults_file) { '--defaults-extra-file=/root/.my.cnf' } - - let(:raw_databases) do - <<-SQL_OUTPUT -information_schema -mydb -mysql -performance_schema -test - SQL_OUTPUT - end - - let(:parsed_databases) { %w(information_schema mydb mysql performance_schema test) } - - before :each do - @resource = Puppet::Type::Database.new( - { :charset => 'utf8', :name => 'new_database' } - ) - @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-extra-file=/root/.my.cnf') - end - - describe 'self.instances' do - it 'returns an array of databases' do - subject.stubs(:mysql).with([defaults_file, '-NBe', 'show databases']).returns(raw_databases) - - databases = subject.instances.collect {|x| x.name } - parsed_databases.should match_array(databases) - end - end - - describe 'create' do - it 'makes a user' do - subject.expects(:mysql).with([defaults_file, '-NBe', "create database `#{@resource[:name]}` character set #{@resource[:charset]}"]) - @provider.create - end - end - - describe 'destroy' do - it 'removes a user if present' do - subject.expects(:mysqladmin).with([defaults_file, '-f', 'drop', "#{@resource[:name]}"]) - @provider.destroy - end - end - - describe 'charset' do - it 'returns a charset' do - subject.expects(:mysql).with([defaults_file, '-NBe', "show create database `#{@resource[:name]}`"]).returns('mydbCREATE DATABASE `mydb` /*!40100 DEFAULT CHARACTER SET utf8 */') - @provider.charset.should == 'utf8' - end - end - - describe 'charset=' do - it 'changes the charset' do - subject.expects(:mysql).with([defaults_file, '-NBe', "alter database `#{@resource[:name]}` CHARACTER SET blah"]).returns('0') - - @provider.charset=('blah') - end - end - - describe 'exists?' do - it 'checks if user exists' do - subject.expects(:mysql).with([defaults_file, '-NBe', 'show databases']).returns('information_schema\nmydb\nmysql\nperformance_schema\ntest') - @provider.exists? - end - end - - describe 'self.defaults_file' do - it 'sets --defaults-extra-file' do - File.stubs(:file?).with('#{root_home}/.my.cnf').returns(true) - @provider.defaults_file.should == '--defaults-extra-file=/root/.my.cnf' - end - end - -end diff --git a/spec/unit/puppet/provider/database_grant/mysql_spec.rb b/spec/unit/puppet/provider/database_grant/mysql_spec.rb deleted file mode 100644 index 4d9484d04..000000000 --- a/spec/unit/puppet/provider/database_grant/mysql_spec.rb +++ /dev/null @@ -1,95 +0,0 @@ -require 'puppet' -require 'mocha/api' -require 'spec_helper' -RSpec.configure do |config| - config.mock_with :mocha -end -provider_class = Puppet::Type.type(:database_grant).provider(:mysql) -describe provider_class do - let(:root_home) { '/root' } - - before :each do - @resource = Puppet::Type::Database_grant.new( - { :privileges => 'all', :provider => 'mysql', :name => 'user@host'} - ) - @provider = provider_class.new(@resource) - Facter.stubs(:value).with(:root_home).returns(root_home) - File.stubs(:file?).with("#{root_home}/.my.cnf").returns(true) - end - - it 'should query privileges from the database' do - provider_class.expects(:mysql) .with(["--defaults-extra-file=#{root_home}/.my.cnf", 'mysql', '-Be', 'describe user']).returns <<-EOT -Field Type Null Key Default Extra -Host char(60) NO PRI -User char(16) NO PRI -Password char(41) NO -Select_priv enum('N','Y') NO N -Insert_priv enum('N','Y') NO N -Update_priv enum('N','Y') NO N -EOT - provider_class.expects(:mysql).with(["--defaults-extra-file=#{root_home}/.my.cnf", 'mysql', '-Be', 'describe db']).returns <<-EOT -Field Type Null Key Default Extra -Host char(60) NO PRI -Db char(64) NO PRI -User char(16) NO PRI -Select_priv enum('N','Y') NO N -Insert_priv enum('N','Y') NO N -Update_priv enum('N','Y') NO N -EOT - provider_class.user_privs.should == %w(Select_priv Insert_priv Update_priv) - provider_class.db_privs.should == %w(Select_priv Insert_priv Update_priv) - end - - it 'should query set privileges' do - provider_class.expects(:mysql).with(["--defaults-extra-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 -EOT - @provider.privileges.should == %w(Select_priv Update_priv) - end - - it 'should recognize when all privileges are set' do - provider_class.expects(:mysql).with(["--defaults-extra-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 -EOT - @provider.all_privs_set?.should == true - end - - it 'should recognize when all privileges are not set' do - provider_class.expects(:mysql).with(["--defaults-extra-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 -EOT - @provider.all_privs_set?.should == false - end - - it 'should be able to set all privileges' do - provider_class.expects(:mysql).with(["--defaults-extra-file=#{root_home}/.my.cnf", 'mysql', '-NBe', "SELECT '1' FROM user WHERE user='user' AND host='host'"]).returns "1\n" - provider_class.expects(:mysql).with(["--defaults-extra-file=#{root_home}/.my.cnf", 'mysql', '-Be', "update user set Select_priv = 'Y', Insert_priv = 'Y', Update_priv = 'Y' where user='user' and host='host'"]) - provider_class.expects(:mysqladmin).with(%W(--defaults-extra-file=#{root_home}/.my.cnf flush-privileges)) - @provider.privileges=(%w(all)) - end - - it 'should be able to set partial privileges' do - provider_class.expects(:mysql).with(["--defaults-extra-file=#{root_home}/.my.cnf", 'mysql', '-NBe', "SELECT '1' FROM user WHERE user='user' AND host='host'"]).returns "1\n" - provider_class.expects(:mysql).with(["--defaults-extra-file=#{root_home}/.my.cnf", 'mysql', '-Be', "update user set Select_priv = 'Y', Insert_priv = 'N', Update_priv = 'Y' where user='user' and host='host'"]) - provider_class.expects(:mysqladmin).with(%W(--defaults-extra-file=#{root_home}/.my.cnf flush-privileges)) - @provider.privileges=(%w(Select_priv Update_priv)) - end - - it 'should be case insensitive' do - provider_class.expects(:mysql).with(["--defaults-extra-file=#{root_home}/.my.cnf", 'mysql', '-NBe', "SELECT '1' FROM user WHERE user='user' AND host='host'"]).returns "1\n" - provider_class.expects(:mysql).with(["--defaults-extra-file=#{root_home}/.my.cnf", 'mysql', '-Be', "update user set Select_priv = 'Y', Insert_priv = 'Y', Update_priv = 'Y' where user='user' and host='host'"]) - provider_class.expects(:mysqladmin).with(["--defaults-extra-file=#{root_home}/.my.cnf", 'flush-privileges']) - @provider.privileges=(%w(SELECT_PRIV insert_priv UpDaTe_pRiV)) - end - - it 'should not pass --defaults-extra-file if $root_home/.my.cnf is absent' do - File.stubs(:file?).with("#{root_home}/.my.cnf").returns(false) - provider_class.expects(:mysql).with(['mysql', '-NBe', "SELECT '1' FROM user WHERE user='user' AND host='host'"]).returns "1\n" - provider_class.expects(:mysql).with(['mysql', '-Be', "update user set Select_priv = 'Y', Insert_priv = 'N', Update_priv = 'Y' where user='user' and host='host'"]) - provider_class.expects(:mysqladmin).with(%w(flush-privileges)) - @provider.privileges=(%w(Select_priv Update_priv)) - end -end diff --git a/spec/unit/puppet/provider/database_user/mysql_spec.rb b/spec/unit/puppet/provider/database_user/mysql_spec.rb deleted file mode 100644 index d85306822..000000000 --- a/spec/unit/puppet/provider/database_user/mysql_spec.rb +++ /dev/null @@ -1,119 +0,0 @@ -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-extra-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) { %w(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', - :max_user_connections => '10' - } - ) - @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-extra-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', "grant usage on *.* to 'joe'@'localhost' identified by PASSWORD - '*6C8989366EAF75BB670AD8EA7A7FC1176A95CEF4' with max_user_connections 10"]) - @provider.expects(:exists?).returns(true) - @provider.create.should be_truthy - 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_truthy - 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 'max_user_connections' do - it 'returns max user connections' do - subject.expects(:mysql).with([defaults_file, 'mysql', '-NBe', "select max_user_connections from mysql.user where CONCAT(user, '@', host) = 'joe@localhost'"]).returns('10') - @provider.max_user_connections.should == '10' - end - end - - describe 'max_user_connections=' do - it 'changes max user connections' do - subject.expects(:mysql).with([defaults_file, 'mysql', '-e', "grant usage on *.* to 'joe'@'localhost' with max_user_connections 42"]).returns('0') - @provider.expects(:max_user_connections).returns('42') - @provider.max_user_connections=('42') - 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_truthy - 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-extra-file' do - File.stubs(:file?).with('#{root_home}/.my.cnf').returns(true) - @provider.defaults_file.should == '--defaults-extra-file=/root/.my.cnf' - end - end - -end