Skip to content
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

Refactor policy resource #587

Merged
merged 3 commits into from
Apr 6, 2022
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
3 changes: 1 addition & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -515,14 +515,13 @@ Sets or clears a RabbitMQ [policy](https://www.rabbitmq.com/parameters.html#poli

- `:set` sets a `policy`
- `:clear` clears a `policy`
- `:list` lists `policy`s

### Examples

``` ruby
rabbitmq_policy "queue-length-limit" do
pattern "^limited\\.*"
parameters ({"max-length" => "3000"})
michaelklishin marked this conversation as resolved.
Show resolved Hide resolved
definition ({"max-length" => "3000"})
priority 1
action :set
end
Expand Down
11 changes: 11 additions & 0 deletions libraries/default.rb
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,17 @@ def format_kernel_parameters # rubocop:disable all
rendered.join(",\n")
end

def get_policy(name, vhost)
# Returns JSON of a policy in a vhost
# Returns false if the policy does not exist
cmd = "rabbitmqctl list_policies --vhost #{Shellwords.escape vhost} --formatter json"
cmd = Mixlib::ShellOut.new(cmd, env: shell_environment).run_command
pol = JSON.parse(cmd.stdout).select { |p| p['name'] == name }.first
return false unless pol
pol['definition'] = JSON.parse(pol['definition']) unless pol['definition'].is_a?(Hash)
pol
end

def format_ssl_versions
Array(node['rabbitmq']['ssl_versions']).map { |n| "'#{n}'" }.join(',')
end
Expand Down
5 changes: 1 addition & 4 deletions providers/erlang_package_from_cloudsmith.rb
Original file line number Diff line number Diff line change
Expand Up @@ -53,12 +53,9 @@
retries new_resource.retries
retry_delay new_resource.retry_delay unless new_resource.retry_delay.nil?
action :install
notifies :reload, 'ohai[reload_packages]', :immediately
end
end

ohai 'reload' do
action :reload
end
end

if platform_family?('rhel', 'fedora', 'amazon')
Expand Down
100 changes: 0 additions & 100 deletions providers/policy.rb

This file was deleted.

2 changes: 1 addition & 1 deletion recipes/policies.rb
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
node['rabbitmq']['policies'].each do |name, policy|
rabbitmq_policy name do
pattern policy['pattern']
parameters policy['params']
definition policy['params']
priority policy['priority']
vhost policy['vhost']
apply_to policy['apply_to']
Expand Down
63 changes: 56 additions & 7 deletions resources/policy.rb
Original file line number Diff line number Diff line change
Expand Up @@ -20,14 +20,63 @@
# limitations under the License.
#

include RabbitMQ::CoreHelpers

unified_mode true if respond_to?(:unified_mode)

actions :set, :clear, :list
default_action :set

attribute :policy, :kind_of => String, :name_attribute => true
attribute :pattern, :kind_of => String
attribute :parameters, :kind_of => Hash
attribute :priority, :kind_of => Integer
attribute :vhost, :kind_of => String
attribute :apply_to, :kind_of => String, :equal_to => %w(all queues exchanges)
property :policy, String, name_property: true
property :pattern, String
property :definition, Hash
property :priority, Integer, default: 0
property :apply_to, String, :equal_to => %w(all queues exchanges), default: 'all'
property :vhost, String, default: '/'

deprecated_property_alias 'parameters',
'definition',
'The \"parameters\" property has been renamed \"definition\". '\
'Please update your cookbooks to use the new property name.'

load_current_value do |new_resource|
p = get_policy(new_resource.policy, new_resource.vhost)

current_value_does_not_exist! unless p

pattern p['pattern']
definition p['definition']
apply_to p['apply-to']
priority p['priority']
end

action :set do
# These properties are only required for the :set action
[:pattern, :definition].each do |prop|
raise(
Chef::Exceptions::ValidationFailed,
"#{prop} is a required property"
) unless property_is_set?(prop)
end

converge_if_changed do
cmd = "rabbitmqctl -q set_policy -p #{new_resource.vhost}"
cmd += " --apply-to #{new_resource.apply_to}"
cmd += " #{new_resource.policy}"
cmd += " \"#{new_resource.pattern}\""
cmd += " '#{new_resource.definition.to_json}'"
cmd += " --priority #{new_resource.priority}"

execute "set_policy #{new_resource.policy} on vhost #{new_resource.vhost}" do
command cmd
environment shell_environment
end
end
end

action :clear do
execute "clear_policy #{new_resource.policy} from vhost #{new_resource.vhost}" do
command "rabbitmqctl clear_policy #{new_resource.policy} -p #{new_resource.vhost}"
environment shell_environment
only_if { get_policy(new_resource.policy, new_resource.vhost) }
end
end
108 changes: 108 additions & 0 deletions spec/policy_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
require 'spec_helper'

describe 'rabbitmq_policy' do
step_into :rabbitmq_policy

platform 'ubuntu'

context 'when policies do not exist' do
before do
shellout = double
allow(Mixlib::ShellOut).to receive(:new).with(
/rabbitmqctl list_policies/, {env: { 'HOME' => // } }
).and_return(shellout)
allow(shellout).to receive(:run_command).and_return(shellout)
allow(shellout).to receive(:stdout).and_return('[]')
end

recipe do
rabbitmq_policy 'potato' do
pattern '^(?!amq\\.).*'
definition(
'ha-mode' => 'exactly',
'ha-params' => 2,
'ha-sync-mode' => 'automatic'
)
action :set
end

rabbitmq_policy 'tomato' do
action :clear
end
end

it 'sets the policy' do
is_expected.to run_execute('set_policy potato on vhost /').with(
command: 'rabbitmqctl -q set_policy -p / --apply-to all potato "^(?!amq\\.).*" '\
'\'{"ha-mode":"exactly","ha-params":2,"ha-sync-mode":"automatic"}\' --priority 0'
)
is_expected.to_not run_execute('clear_policy tomato from vhost /')
end
end

context 'when policies already exist' do
before do
shellout = double
allow(Mixlib::ShellOut).to receive(:new).with(
/rabbitmqctl list_policies/, {env: { 'HOME' => // } }
).and_return(shellout)
allow(shellout).to receive(:run_command).and_return(shellout)
allow(shellout).to receive(:stdout).and_return(
'[
{
"name":"policy1",
"pattern":"pattern1",
"definition":{"key1":"val1"},
"apply-to":"all",
"priority":0
},
{
"name":"policy2",
"pattern":"pattern2",
"definition":{"key2":"val2"},
"apply-to":"queues",
"priority":1
},
{
"name":"policy3",
"pattern":"pattern3",
"definition":{"key3":"val3"},
"apply-to":"queues",
"priority":2
}
]'
)
end

recipe do
rabbitmq_policy 'policy1' do
pattern 'pattern1'
definition('key1' => 'val1', 'extrakey' => 'extraval')
apply_to 'all'
priority 0
action :set
end

rabbitmq_policy 'policy2' do
pattern 'pattern2'
definition('key2' => 'val2')
apply_to 'queues'
priority 1
action :set
end

rabbitmq_policy 'policy3' do
action :clear
end
end

it 'amends only the policies that have changed' do
is_expected.to run_execute('set_policy policy1 on vhost /').with(
command: 'rabbitmqctl -q set_policy -p / --apply-to all policy1 "pattern1" '\
'\'{"key1":"val1","extrakey":"extraval"}\' --priority 0'
)
is_expected.to_not run_execute('set_policy policy2 on vhost /')
is_expected.to run_execute('clear_policy policy3 from vhost /')
end
end
end
2 changes: 1 addition & 1 deletion test/cookbooks/rabbitmq_test/recipes/lwrps.rb
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@

rabbitmq_policy 'queue_length_limit' do
pattern 'limited.*'
parameters 'max-length' => 1000
definition 'max-length' => 1000
apply_to 'queues'
action :set
end
Expand Down