-
Notifications
You must be signed in to change notification settings - Fork 52
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #390 from mkrakowitzer/set_parameter
Adds support for rabbitmqctl command option set_parameter
- Loading branch information
Showing
6 changed files
with
347 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,84 @@ | ||
require 'json' | ||
require 'puppet/util/package' | ||
|
||
require File.expand_path(File.join(File.dirname(__FILE__), '..', 'rabbitmqctl')) | ||
Puppet::Type.type(:rabbitmq_parameter).provide(:rabbitmqctl, :parent => Puppet::Provider::Rabbitmqctl) do | ||
|
||
defaultfor :feature => :posix | ||
|
||
# cache parameters | ||
def self.parameters(name, vhost) | ||
@parameters = {} unless @parameters | ||
unless @parameters[vhost] | ||
@parameters[vhost] = {} | ||
self.run_with_retries { | ||
rabbitmqctl('list_parameters', '-q', '-p', vhost) | ||
}.split(/\n/).each do |line| | ||
if line =~ /^(\S+)\s+(\S+)\s+(\S+)$/ | ||
@parameters[vhost][$2] = { | ||
:component_name => $1, | ||
:value => JSON.parse($3), | ||
} | ||
else | ||
raise Puppet::Error, "cannot parse line from list_parameter:#{line}" | ||
end | ||
end | ||
end | ||
@parameters[vhost][name] | ||
end | ||
|
||
def parameters(name, vhost) | ||
self.class.parameters(vhost, name) | ||
end | ||
|
||
def should_parameter | ||
@should_parameter ||= resource[:name].rpartition('@').first | ||
end | ||
|
||
def should_vhost | ||
@should_vhost ||= resource[:name].rpartition('@').last | ||
end | ||
|
||
def create | ||
set_parameter | ||
end | ||
|
||
def destroy | ||
rabbitmqctl('clear_parameter', '-p', should_vhost, 'shovel', should_parameter) | ||
end | ||
|
||
def exists? | ||
parameters(should_vhost, should_parameter) | ||
end | ||
|
||
def component_name | ||
parameters(should_vhost, should_parameter)[:component_name] | ||
end | ||
|
||
def component_name=(component_name) | ||
set_parameter | ||
end | ||
|
||
def value | ||
parameters(should_vhost, should_parameter)[:value] | ||
end | ||
|
||
def value=(value) | ||
set_parameter | ||
end | ||
|
||
def set_parameter | ||
unless @set_parameter | ||
@set_parameter = true | ||
resource[:value] ||= value | ||
resource[:component_name] ||= component_name | ||
rabbitmqctl('set_parameter', | ||
'-p', should_vhost, | ||
resource[:component_name], | ||
should_parameter, | ||
resource[:value].to_json | ||
) | ||
end | ||
end | ||
|
||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,73 @@ | ||
Puppet::Type.newtype(:rabbitmq_parameter) do | ||
|
||
desc 'Type for managing rabbitmq parameters' | ||
|
||
ensurable do | ||
defaultto(:present) | ||
newvalue(:present) do | ||
provider.create | ||
end | ||
newvalue(:absent) do | ||
provider.destroy | ||
end | ||
end | ||
|
||
autorequire(:service) { 'rabbitmq-server' } | ||
|
||
validate do | ||
fail('component_name parameter is required.') if self[:ensure] == :present and self[:component_name].nil? | ||
fail('value parameter is required.') if self[:ensure] == :present and self[:value].nil? | ||
end | ||
|
||
newparam(:name, :namevar => true) do | ||
desc 'combination of name@vhost to set parameter for' | ||
newvalues(/^\S+@\S+$/) | ||
end | ||
|
||
newproperty(:component_name) do | ||
desc 'The component_name to use when setting parameter, eg: shovel or federation' | ||
validate do |value| | ||
resource.validate_component_name(value) | ||
end | ||
end | ||
|
||
newproperty(:value) do | ||
desc 'A hash of values to use with the component name you are setting' | ||
validate do |value| | ||
resource.validate_value(value) | ||
end | ||
munge do |value| | ||
resource.munge_value(value) | ||
end | ||
end | ||
|
||
autorequire(:rabbitmq_vhost) do | ||
[self[:name].split('@')[1]] | ||
end | ||
|
||
def validate_component_name(value) | ||
if value.empty? | ||
raise ArgumentError, "component_name must be defined" | ||
end | ||
end | ||
|
||
def validate_value(value) | ||
unless [Hash].include?(value.class) | ||
raise ArgumentError, "Invalid value" | ||
end | ||
value.each do |k,v| | ||
unless [String].include?(v.class) | ||
raise ArgumentError, "Invalid value" | ||
end | ||
end | ||
end | ||
|
||
def munge_value(value) | ||
value.each do |k,v| | ||
if (v =~ /\A[-+]?[0-9]+\z/) | ||
value[k] = v.to_i | ||
end | ||
end | ||
value | ||
end | ||
end |
87 changes: 87 additions & 0 deletions
87
spec/unit/puppet/provider/rabbitmq_parameter/rabbitmqctl_spec.rb
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,87 @@ | ||
require 'puppet' | ||
require 'mocha' | ||
|
||
RSpec.configure do |config| | ||
config.mock_with :mocha | ||
end | ||
|
||
describe Puppet::Type.type(:rabbitmq_parameter).provider(:rabbitmqctl) do | ||
|
||
let(:resource) do | ||
Puppet::Type.type(:rabbitmq_parameter).new( | ||
:name => 'documentumShovel@/', | ||
:component_name => 'shovel', | ||
:value => { | ||
'src-uri' => 'amqp://', | ||
'src-queue' => 'my-queue', | ||
'dest-uri' => 'amqp://remote-server', | ||
'dest-queue' => 'another-queue', | ||
}, | ||
:provider => described_class.name | ||
) | ||
end | ||
|
||
let(:provider) { resource.provider } | ||
|
||
after(:each) do | ||
described_class.instance_variable_set(:@parameters, nil) | ||
end | ||
|
||
it 'should accept @ in parameter name' do | ||
resource = Puppet::Type.type(:rabbitmq_parameter).new( | ||
:name => 'documentumShovel@/', | ||
:component_name => 'shovel', | ||
:value => { | ||
'src-uri' => 'amqp://', | ||
'src-queue' => 'my-queue', | ||
'dest-uri' => 'amqp://remote-server', | ||
'dest-queue' => 'another-queue', | ||
}, | ||
:provider => described_class.name | ||
) | ||
provider = described_class.new(resource) | ||
provider.should_parameter.should == 'documentumShovel' | ||
provider.should_vhost.should == '/' | ||
end | ||
|
||
it 'should fail with invalid output from list' do | ||
provider.class.expects(:rabbitmqctl).with('list_parameters', '-q', '-p', '/').returns 'foobar' | ||
expect { provider.exists? }.to raise_error(Puppet::Error, /cannot parse line from list_parameter/) | ||
end | ||
|
||
it 'should match parameters from list' do | ||
provider.class.expects(:rabbitmqctl).with('list_parameters', '-q', '-p', '/').returns <<-EOT | ||
shovel documentumShovel {"src-uri":"amqp://","src-queue":"my-queue","dest-uri":"amqp://remote-server","dest-queue":"another-queue"} | ||
EOT | ||
provider.exists?.should == { | ||
:component_name => 'shovel', | ||
:value => { | ||
'src-uri' => 'amqp://', | ||
'src-queue' => 'my-queue', | ||
'dest-uri' => 'amqp://remote-server', | ||
'dest-queue' => 'another-queue', | ||
} | ||
} | ||
end | ||
|
||
it 'should not match an empty list' do | ||
provider.class.expects(:rabbitmqctl).with('list_parameters', '-q', '-p', '/').returns '' | ||
provider.exists?.should == nil | ||
end | ||
|
||
it 'should destroy parameter' do | ||
provider.expects(:rabbitmqctl).with('clear_parameter', '-p', '/', 'shovel', 'documentumShovel') | ||
provider.destroy | ||
end | ||
|
||
it 'should only call set_parameter once' do | ||
provider.expects(:rabbitmqctl).with('set_parameter', | ||
'-p', '/', | ||
'shovel', | ||
'documentumShovel', | ||
'{"src-uri":"amqp://","src-queue":"my-queue","dest-uri":"amqp://remote-server","dest-queue":"another-queue"}' | ||
).once | ||
provider.create | ||
end | ||
|
||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,81 @@ | ||
require 'puppet' | ||
require 'puppet/type/rabbitmq_parameter' | ||
|
||
describe Puppet::Type.type(:rabbitmq_parameter) do | ||
|
||
before do | ||
@parameter = Puppet::Type.type(:rabbitmq_parameter).new( | ||
:name => 'documentumShovel@/', | ||
:component_name => 'shovel', | ||
:value => { | ||
'src-uri' => 'amqp://myremote-server', | ||
'src-queue' => 'queue.docs.outgoing', | ||
'dest-uri' => 'amqp://', | ||
'dest-queue' => 'queue.docs.incoming', | ||
}) | ||
end | ||
|
||
it 'should accept a valid name' do | ||
@parameter[:name] = 'documentumShovel@/' | ||
@parameter[:name].should == 'documentumShovel@/' | ||
end | ||
|
||
it 'should require a name' do | ||
expect { | ||
Puppet::Type.type(:rabbitmq_parameter).new({}) | ||
}.to raise_error(Puppet::Error, 'Title or name must be provided') | ||
end | ||
|
||
it 'should fail when name does not have a @' do | ||
expect { | ||
@parameter[:name] = 'documentumShovel' | ||
}.to raise_error(Puppet::Error, /Valid values match/) | ||
end | ||
|
||
it 'should accept a string' do | ||
@parameter[:component_name] = 'mystring' | ||
@parameter[:component_name].should == 'mystring' | ||
end | ||
|
||
it 'should not be empty' do | ||
expect { | ||
@parameter[:component_name] = '' | ||
}.to raise_error(Puppet::Error, /component_name must be defined/) | ||
end | ||
|
||
it 'should accept a valid hash for value' do | ||
value = {'message-ttl' => '1800000'} | ||
@parameter[:value] = value | ||
@parameter[:value].should == value | ||
end | ||
|
||
it 'should not accept invalid hash for definition' do | ||
expect { | ||
@parameter[:value] = '' | ||
}.to raise_error(Puppet::Error, /Invalid value/) | ||
|
||
expect { | ||
@parameter[:value] = 'guest' | ||
}.to raise_error(Puppet::Error, /Invalid value/) | ||
|
||
expect { | ||
@parameter[:value] = {'message-ttl' => ['999', '100']} | ||
}.to raise_error(Puppet::Error, /Invalid value/) | ||
end | ||
|
||
it 'should accept string as myparameter' do | ||
value = {'myparameter' => 'mystring'} | ||
@parameter[:value] = value | ||
@parameter[:value]['myparameter'].should be_a(String) | ||
@parameter[:value]['myparameter'].should == 'mystring' | ||
end | ||
|
||
|
||
it 'should convert to integer when string only contains numbers' do | ||
value = {'myparameter' => '1800000'} | ||
@parameter[:value] = value | ||
@parameter[:value]['myparameter'].should be_a(Fixnum) | ||
@parameter[:value]['myparameter'].should == 1800000 | ||
end | ||
|
||
end |