Skip to content

Commit

Permalink
Merge pull request #676 from fatmcgav/fix_up_674
Browse files Browse the repository at this point in the history
Support policy format change in v3.7.0 - #671 (Replaces #674)
  • Loading branch information
bastelfreak authored Jan 11, 2018
2 parents 66bf6a5 + a3673c3 commit f5e1ffe
Show file tree
Hide file tree
Showing 2 changed files with 66 additions and 29 deletions.
29 changes: 21 additions & 8 deletions lib/puppet/provider/rabbitmq_policy/rabbitmqctl.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,25 +6,38 @@
confine feature: :posix

# cache policies
def self.policies(name, vhost)
def self.policies(vhost, name)
@policies = {} unless @policies
unless @policies[vhost]
@policies[vhost] = {}
policy_list = run_with_retries do
rabbitmqctl('list_policies', '-q', '-p', vhost)
end

# rabbitmq<3.2 does not support the applyto field
# 1 2 3? 4 5 6
# / ha-all all .* {"ha-mode":"all","ha-sync-mode":"automatic"} 0 << This is for RabbitMQ v < 3.7.0
# / ha-all .* all {"ha-mode":"all","ha-sync-mode":"automatic"} 0 << This is for RabbitMQ v >= 3.7.0
if Puppet::Util::Package.versioncmp(rabbitmq_version, '3.7') >= 0
regex = %r{^(\S+)\s+(\S+)\s+(\S+)\s+(all|exchanges|queues)?\s+(\S+)\s+(\d+)$}
applyto_index = 4
pattern_index = 3
else
regex = %r{^(\S+)\s+(\S+)\s+(all|exchanges|queues)?\s*(\S+)\s+(\S+)\s+(\d+)$}
applyto_index = 3
pattern_index = 4
end

policy_list.split(%r{\n}).each do |line|
# rabbitmq<3.2 does not support the applyto field
# 1 2 3? 4 5 6
# / ha-all all .* {"ha-mode":"all","ha-sync-mode":"automatic"} 0
raise Puppet::Error, "cannot parse line from list_policies:#{line}" unless line =~ %r{^(\S+)\s+(\S+)\s+(all|exchanges|queues)?\s*(\S+)\s+(\S+)\s+(\d+)$}
raise Puppet::Error, "cannot parse line from list_policies:#{line}" unless line =~ regex
n = Regexp.last_match(2)
applyto = Regexp.last_match(3) || 'all'
applyto = Regexp.last_match(applyto_index) || 'all'
priority = Regexp.last_match(6)
definition = JSON.parse(Regexp.last_match(5))
# be aware that the gsub will reset the captures
# from the regexp above
pattern = Regexp.last_match(4).to_s.gsub(%r{\\\\}, '\\')
pattern = Regexp.last_match(pattern_index).to_s.gsub(%r{\\\\}, '\\')

@policies[vhost][n] = {
applyto: applyto,
pattern: pattern,
Expand All @@ -36,7 +49,7 @@ def self.policies(name, vhost)
@policies[vhost][name]
end

def policies(name, vhost)
def policies(vhost, name)
self.class.policies(vhost, name)
end

Expand Down
66 changes: 45 additions & 21 deletions spec/unit/puppet/provider/rabbitmq_policy/rabbitmqctl_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,10 @@
pattern: '.*',
definition: {
'ha-mode' => 'all'
},
provider: described_class.name
}
)
end
let(:provider) { resource.provider }
let(:provider) { described_class.new(resource) }

after do
described_class.instance_variable_set(:@policies, nil)
Expand Down Expand Up @@ -40,39 +39,64 @@
end

it 'fails with invalid output from list' do
provider.class.expects(:rabbitmqctl).with('-q', 'status').returns '{rabbit,"RabbitMQ","3.1.5"}'
provider.class.expects(:rabbitmqctl).with('list_policies', '-q', '-p', '/').returns 'foobar'
expect { provider.exists? }.to raise_error(Puppet::Error, %r{cannot parse line from list_policies})
end

it 'matches policies from list (>=3.2.0)' do
provider.class.expects(:rabbitmqctl).with('list_policies', '-q', '-p', '/').returns <<-EOT
context 'with RabbitMQ version >=3.7.0' do
it 'matches policies from list' do
provider.class.expects(:rabbitmq_version).returns '3.7.0'
provider.class.expects(:rabbitmqctl).with('list_policies', '-q', '-p', '/').returns <<-EOT
/ ha-all .* all {"ha-mode":"all","ha-sync-mode":"automatic"} 0
/ test .* exchanges {"ha-mode":"all"} 0
EOT
expect(provider.exists?).to eq(applyto: 'all',
pattern: '.*',
priority: '0',
definition: {
'ha-mode' => 'all',
'ha-sync-mode' => 'automatic'
})
end
end

context 'with RabbitMQ version >=3.2.0 and < 3.7.0' do
it 'matches policies from list' do
provider.class.expects(:rabbitmq_version).returns '3.6.9'
provider.class.expects(:rabbitmqctl).with('list_policies', '-q', '-p', '/').returns <<-EOT
/ ha-all all .* {"ha-mode":"all","ha-sync-mode":"automatic"} 0
/ test exchanges .* {"ha-mode":"all"} 0
EOT
expect(provider.exists?).to eq(applyto: 'all',
pattern: '.*',
priority: '0',
definition: {
'ha-mode' => 'all',
'ha-sync-mode' => 'automatic'
})
expect(provider.exists?).to eq(applyto: 'all',
pattern: '.*',
priority: '0',
definition: {
'ha-mode' => 'all',
'ha-sync-mode' => 'automatic'
})
end
end

it 'matches policies from list (<3.2.0)' do
provider.class.expects(:rabbitmqctl).with('list_policies', '-q', '-p', '/').returns <<-EOT
context 'with RabbitMQ version <3.2.0' do
it 'matches policies from list (<3.2.0)' do
provider.class.expects(:rabbitmq_version).returns '3.1.5'
provider.class.expects(:rabbitmqctl).with('list_policies', '-q', '-p', '/').returns <<-EOT
/ ha-all .* {"ha-mode":"all","ha-sync-mode":"automatic"} 0
/ test .* {"ha-mode":"all"} 0
EOT
expect(provider.exists?).to eq(applyto: 'all',
pattern: '.*',
priority: '0',
definition: {
'ha-mode' => 'all',
'ha-sync-mode' => 'automatic'
})
expect(provider.exists?).to eq(applyto: 'all',
pattern: '.*',
priority: '0',
definition: {
'ha-mode' => 'all',
'ha-sync-mode' => 'automatic'
})
end
end

it 'does not match an empty list' do
provider.class.expects(:rabbitmqctl).with('-q', 'status').returns '{rabbit,"RabbitMQ","3.1.5"}'
provider.class.expects(:rabbitmqctl).with('list_policies', '-q', '-p', '/').returns ''
expect(provider.exists?).to eq(nil)
end
Expand Down

0 comments on commit f5e1ffe

Please sign in to comment.