Add type & provider for managing plugins

This commit is contained in:
Daniël van Eeden 2015-01-19 22:00:25 +01:00
parent 0623654438
commit 74132ec038
7 changed files with 230 additions and 0 deletions

View file

@ -566,6 +566,17 @@ mysql_grant { 'root@localhost/mysql.user':
}
```
####mysql_plugin
`mysql_plugin` can be used to load plugins into the MySQL Server.
```puppet
mysql_plugin { 'auth_socket':
ensure => 'present',
soname => 'auth_socket.so',
}
```
##Limitations
This module has been tested on:
@ -603,4 +614,5 @@ This module is based on work by David Schmitt. The following contributors have c
* William Van Hevelingen
* Michael Arnold
* Chris Weyl
* Daniël van Eeden

View file

@ -0,0 +1,53 @@
require File.expand_path(File.join(File.dirname(__FILE__), '..', 'mysql'))
Puppet::Type.type(:mysql_plugin).provide(:mysql, :parent => Puppet::Provider::Mysql) do
desc 'Manages MySQL plugins.'
commands :mysql => 'mysql'
def self.instances
mysql([defaults_file, '-NBe', 'show plugins'].compact).split("\n").collect do |line|
name, status, type, library, license = line.split(/\t/)
new(:name => name,
:ensure => :present,
:soname => library
)
end
end
# We iterate over each mysql_plugin entry in the catalog and compare it against
# the contents of the property_hash generated by self.instances
def self.prefetch(resources)
plugins = instances
resources.keys.each do |plugin|
if provider = plugins.find { |pl| pl.name == plugin }
resources[plugin].provider = provider
end
end
end
def create
# Use plugin_name.so as soname if it's not specified. This won't work on windows as
# there it should be plugin_name.dll
@resource[:soname].nil? ? (soname=@resource[:name] + '.so') : (soname=@resource[:soname])
mysql([defaults_file, '-NBe', "install plugin #{@resource[:name]} soname '#{soname}'"].compact)
@property_hash[:ensure] = :present
@property_hash[:soname] = @resource[:soname]
exists? ? (return true) : (return false)
end
def destroy
mysql([defaults_file, '-NBe', "uninstall plugin #{@resource[:name]}"].compact)
@property_hash.clear
exists? ? (return false) : (return true)
end
def exists?
@property_hash[:ensure] == :present || false
end
mk_resource_methods
end

View file

@ -0,0 +1,17 @@
Puppet::Type.newtype(:mysql_plugin) do
@doc = 'Manage MySQL plugins.'
ensurable
autorequire(:file) { '/root/.my.cnf' }
newparam(:name, :namevar => true) do
desc 'The name of the MySQL plugin to manage.'
end
newproperty(:soname) do
desc 'The name of the library'
newvalue(/^\w+\.\w+$/)
end
end

View file

@ -0,0 +1,34 @@
require 'spec_helper_acceptance'
describe 'mysql_plugin' do
describe 'setup' do
it 'should work with no errors' do
pp = <<-EOS
class { 'mysql::server': }
EOS
apply_manifest(pp, :catch_failures => true)
end
end
describe 'load plugin' do
it 'should work without errors' do
pp = <<-EOS
mysql_plugin { 'auth_socket':
ensure => present,
soname => 'auth_socket.so',
}
EOS
apply_manifest(pp, :catch_failures => true)
end
it 'should find the plugin' do
shell("mysql -NBe \"select plugin_name from information_schema.plugins where plugin_name='auth_socket'\"") do |r|
expect(r.stdout).to match(/^auth_socket$/)
expect(r.stderr).to be_empty
end
end
end
end

View file

@ -0,0 +1,71 @@
require 'spec_helper'
describe Puppet::Type.type(:mysql_plugin).provider(:mysql) do
let(:defaults_file) { '--defaults-extra-file=/root/.my.cnf' }
let(:resource) { Puppet::Type.type(:mysql_plugin).new(
{ :ensure => :present,
:soname => 'auth_socket.so',
:name => 'auth_socket',
:provider => described_class.name
}
)}
let(:provider) { resource.provider }
before :each do
Facter.stubs(:value).with(:root_home).returns('/root')
Puppet::Util.stubs(:which).with('mysql').returns('/usr/bin/mysql')
File.stubs(:file?).with('/root/.my.cnf').returns(true)
provider.class.stubs(:mysql).with([defaults_file, '-NBe', 'show plugins']).returns('auth_socket ACTIVE AUTHENTICATION auth_socket.so GPL')
end
let(:instance) { provider.class.instances.first }
describe 'self.prefetch' do
it 'exists' do
provider.class.instances
provider.class.prefetch({})
end
end
describe 'create' do
it 'loads a plugin' do
provider.expects(:mysql).with([defaults_file, '-NBe', "install plugin #{resource[:name]} soname '#{resource[:soname]}'"])
provider.expects(:exists?).returns(true)
expect(provider.create).to be_truthy
end
end
describe 'destroy' do
it 'unloads a plugin if present' do
provider.expects(:mysql).with([defaults_file, '-NBe', "uninstall plugin #{resource[:name]}"])
provider.expects(:exists?).returns(false)
expect(provider.destroy).to be_truthy
end
end
describe 'exists?' do
it 'checks if plugin exists' do
expect(instance.exists?).to be_truthy
end
end
describe 'self.defaults_file' do
it 'sets --defaults-extra-file' do
File.stubs(:file?).with('/root/.my.cnf').returns(true)
expect(provider.defaults_file).to eq '--defaults-extra-file=/root/.my.cnf'
end
it 'fails if file missing' do
File.stubs(:file?).with('/root/.my.cnf').returns(false)
expect(provider.defaults_file).to be_nil
end
end
describe 'soname' do
it 'returns a soname' do
expect(instance.soname).to eq('auth_socket.so')
end
end
end

View file

@ -0,0 +1,24 @@
require 'puppet'
require 'puppet/type/mysql_plugin'
describe Puppet::Type.type(:mysql_plugin) do
before :each do
@plugin = Puppet::Type.type(:mysql_plugin).new(:name => 'test', :soname => 'test.so')
end
it 'should accept a plugin name' do
expect(@plugin[:name]).to eq('test')
end
it 'should accept a library name' do
@plugin[:soname] = 'test.so'
expect(@plugin[:soname]).to eq('test.so')
end
it 'should require a name' do
expect {
Puppet::Type.type(:mysql_plugin).new({})
}.to raise_error(Puppet::Error, 'Title or name must be provided')
end
end

19
tests/mysql_plugin.pp Normal file
View file

@ -0,0 +1,19 @@
class { 'mysql::server':
root_password => 'password'
}
mysql::plugin{ 'validate_password':
ensure => present,
soname => $::osfamily ? {
windows => 'validate_password.dll',
default => 'validate_password.so'
}
}
mysql::plugin{ 'auth_socket':
ensure => present,
soname => $::osfamily ? {
windows => 'auth_socket.dll',
default => 'auth_socket.so'
}
}