/puphpet/puppet/modules/mysql/lib/puppet/type/mysql_grant.rb
Ruby | 101 lines | 89 code | 5 blank | 7 comment | 14 complexity | 2c04c9df671fc9c91d85cb2487d14ece MD5 | raw file
- # This has to be a separate type to enable collecting
- Puppet::Type.newtype(:mysql_grant) do
- @doc = "Manage a MySQL user's rights."
- ensurable
- autorequire(:file) { '/root/.my.cnf' }
- autorequire(:mysql_user) { self[:user] }
- def initialize(*args)
- super
- # Forcibly munge any privilege with 'ALL' in the array to exist of just
- # 'ALL'. This can't be done in the munge in the property as that iterates
- # over the array and there's no way to replace the entire array before it's
- # returned to the provider.
- if self[:ensure] == :present and Array(self[:privileges]).count > 1 and self[:privileges].to_s.include?('ALL')
- self[:privileges] = 'ALL'
- end
- # Sort the privileges array in order to ensure the comparision in the provider
- # self.instances method match. Otherwise this causes it to keep resetting the
- # privileges.
- self[:privileges] = Array(self[:privileges]).map{ |priv|
- # split and sort the column_privileges in the parentheses and rejoin
- if priv.include?('(')
- type, col=priv.strip.split(/\s+|\b/,2)
- type.upcase + " (" + col.slice(1...-1).strip.split(/\s*,\s*/).sort.join(', ') + ")"
- else
- priv.strip.upcase
- end
- }.uniq.reject{|k| k == 'GRANT' or k == 'GRANT OPTION'}.sort!
- end
- validate do
- fail('privileges parameter is required.') if self[:ensure] == :present and self[:privileges].nil?
- fail('table parameter is required.') if self[:ensure] == :present and self[:table].nil?
- fail('user parameter is required.') if self[:ensure] == :present and self[:user].nil?
- fail('name must match user and table parameters') if self[:name] != "#{self[:user]}/#{self[:table]}"
- end
- newparam(:name, :namevar => true) do
- desc 'Name to describe the grant.'
- munge do |value|
- value.delete("'")
- end
- end
- newproperty(:privileges, :array_matching => :all) do
- desc 'Privileges for user'
- end
- newproperty(:table) do
- desc 'Table to apply privileges to.'
- munge do |value|
- value.delete("`")
- end
- newvalues(/.*\..*/,/@/)
- end
- newproperty(:user) do
- desc 'User to operate on.'
- validate do |value|
- # http://dev.mysql.com/doc/refman/5.5/en/identifiers.html
- # If at least one special char is used, string must be quoted
- # http://stackoverflow.com/questions/8055727/negating-a-backreference-in-regular-expressions/8057827#8057827
- if matches = /^(['`"])((?!\1).)*\1@([\w%\.:\-\/]+)$/.match(value)
- user_part = matches[2]
- host_part = matches[3]
- elsif matches = /^([0-9a-zA-Z$_]*)@([\w%\.:\-\/]+)$/.match(value)
- user_part = matches[1]
- host_part = matches[2]
- elsif matches = /^((?!['`"]).*[^0-9a-zA-Z$_].*)@(.+)$/.match(value)
- user_part = matches[1]
- host_part = matches[2]
- else
- raise(ArgumentError, "Invalid database user #{value}")
- end
- mysql_version = Facter.value(:mysql_version)
- unless mysql_version.nil?
- if Puppet::Util::Package.versioncmp(mysql_version, '10.0.0') < 0 and user_part.size > 16
- raise(ArgumentError, 'MySQL usernames are limited to a maximum of 16 characters')
- elsif Puppet::Util::Package.versioncmp(mysql_version, '10.0.0') > 0 and user_part.size > 80
- raise(ArgumentError, 'MySQL usernames are limited to a maximum of 80 characters')
- end
- end
- end
- munge do |value|
- matches = /^((['`"]?).*\2)@(.+)$/.match(value)
- "#{matches[1]}@#{matches[3].downcase}"
- end
- end
- newproperty(:options, :array_matching => :all) do
- desc 'Options to grant.'
- end
- end