Skip to content

Commit

Permalink
Add type & provider for managing plugins
Browse files Browse the repository at this point in the history
  • Loading branch information
dveeden committed Jan 26, 2015
1 parent 0623654 commit 74132ec
Show file tree
Hide file tree
Showing 7 changed files with 230 additions and 0 deletions.
12 changes: 12 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down Expand Up @@ -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

53 changes: 53 additions & 0 deletions lib/puppet/provider/mysql_plugin/mysql.rb
Original file line number Diff line number Diff line change
@@ -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
17 changes: 17 additions & 0 deletions lib/puppet/type/mysql_plugin.rb
Original file line number Diff line number Diff line change
@@ -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
34 changes: 34 additions & 0 deletions spec/acceptance/types/mysql_plugin_spec.rb
Original file line number Diff line number Diff line change
@@ -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
71 changes: 71 additions & 0 deletions spec/unit/puppet/provider/mysql_plugin/mysql_spec.rb
Original file line number Diff line number Diff line change
@@ -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
24 changes: 24 additions & 0 deletions spec/unit/puppet/type/mysql_plugin_spec.rb
Original file line number Diff line number Diff line change
@@ -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 changes: 19 additions & 0 deletions tests/mysql_plugin.pp
Original file line number Diff line number Diff line change
@@ -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'
}
}

0 comments on commit 74132ec

Please sign in to comment.