Skip to content

Add type & provider for managing plugins #641

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jan 27, 2015
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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'
}
}