├── templates └── default │ ├── doterlang.cookie.erb │ ├── rabbitmq.upstart.conf.erb │ ├── rabbitmq-env.conf.erb │ └── rabbitmq.config.erb ├── spec └── spec_helper.rb ├── test └── cookbooks │ └── rabbitmq_test │ ├── README.md │ ├── metadata.rb │ ├── recipes │ ├── cook-2151-3489.rb │ ├── ssl.rb │ ├── cluster.rb │ ├── default.rb │ ├── mgmt_console.rb │ └── lwrps.rb │ └── files │ └── default │ └── tests │ └── minitest │ ├── ssl_test.rb │ ├── cluster_test.rb │ ├── mgmt_console_test.rb │ ├── cook-1724_test.rb │ ├── cook-2151-3489_test.rb │ ├── cook-1684_test.rb │ ├── support │ └── helpers.rb │ ├── lwrps_test.rb │ └── default_test.rb ├── Berksfile ├── .gitignore ├── .rubocop.yml ├── .kitchen.yml ├── Gemfile ├── resources ├── plugin.rb ├── vhost.rb ├── policy.rb └── user.rb ├── recipes ├── mgmt_console.rb ├── plugin_management.rb ├── virtualhost_management.rb ├── policy_management.rb ├── user_management.rb └── default.rb ├── Guardfile ├── libraries ├── default.rb └── matchers.rb ├── Rakefile ├── providers ├── vhost.rb ├── plugin.rb ├── policy.rb └── user.rb ├── .kitchen.cloud.yml ├── attributes └── default.rb ├── metadata.rb ├── CHANGELOG.md ├── README.md ├── TESTING.md ├── .travis.yml ├── LICENSE └── CONTRIBUTING.md /templates/default/doterlang.cookie.erb: -------------------------------------------------------------------------------- 1 | <%= node['rabbitmq']['erlang_cookie'] %> 2 | -------------------------------------------------------------------------------- /spec/spec_helper.rb: -------------------------------------------------------------------------------- 1 | require 'chefspec' 2 | require 'chefspec/berkshelf' 3 | 4 | at_exit { ChefSpec::Coverage.report! } 5 | -------------------------------------------------------------------------------- /test/cookbooks/rabbitmq_test/README.md: -------------------------------------------------------------------------------- 1 | This cookbook is used with test-kitchen to test the parent, rabbitmq cookbook. 2 | -------------------------------------------------------------------------------- /Berksfile: -------------------------------------------------------------------------------- 1 | site :opscode 2 | 3 | metadata 4 | 5 | group :integration do 6 | cookbook 'minitest-handler' 7 | cookbook 'rabbitmq_test', :path => './test/cookbooks/rabbitmq_test' 8 | end 9 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .vagrant 2 | Berksfile.lock 3 | Gemfile.lock 4 | *~ 5 | *# 6 | .#* 7 | \#*# 8 | .*.sw[a-z] 9 | *.un~ 10 | .bundle 11 | .cache 12 | .kitchen 13 | bin 14 | .kitchen.local.yml 15 | .coverage -------------------------------------------------------------------------------- /.rubocop.yml: -------------------------------------------------------------------------------- 1 | AlignParameters: 2 | Enabled: false 3 | 4 | Encoding: 5 | Enabled: false 6 | 7 | LineLength: 8 | Max: 200 9 | 10 | HashSyntax: 11 | EnforcedStyle: hash_rockets 12 | 13 | AsciiComments: 14 | Enabled: false 15 | 16 | MethodLength: 17 | Max: 18 -------------------------------------------------------------------------------- /.kitchen.yml: -------------------------------------------------------------------------------- 1 | driver: 2 | name: vagrant 3 | 4 | provisioner: 5 | name: chef_zero 6 | 7 | platforms: 8 | - name: centos-5.10 9 | - name: centos-6.5 10 | 11 | suites: 12 | - name: default 13 | run_list: 14 | - recipe[minitest-handler] 15 | - recipe[rabbitmq::default] -------------------------------------------------------------------------------- /test/cookbooks/rabbitmq_test/metadata.rb: -------------------------------------------------------------------------------- 1 | maintainer 'Opscode, Inc.' 2 | maintainer_email 'cookbooks@opscode.com' 3 | license 'Apache 2.0' 4 | description 'This cookbook is used with test-kitchen to test the parent, rabbitmq cookbook.' 5 | version '1.0.0' 6 | 7 | depends 'rabbitmq' 8 | -------------------------------------------------------------------------------- /test/cookbooks/rabbitmq_test/recipes/cook-2151-3489.rb: -------------------------------------------------------------------------------- 1 | # 2 | # Cookbook Name:: rabbitmq_test 3 | # Recipe:: cook-2151-3489 4 | # 5 | # This recipe exists to ensure that minitest tests are run. 6 | 7 | include_recipe 'rabbitmq::default' 8 | 9 | # HACK: Give rabbit time to spin up before the tests, it seems 10 | # to be responding that it has started before it really has 11 | execute 'sleep 10' do 12 | action :nothing 13 | subscribes :run, "service[#{node['rabbitmq']['service_name']}]", :delayed 14 | end 15 | -------------------------------------------------------------------------------- /test/cookbooks/rabbitmq_test/recipes/ssl.rb: -------------------------------------------------------------------------------- 1 | # 2 | # Cookbook Name:: rabbitmq_test 3 | # Recipe:: ssl 4 | # 5 | # Copyright 2012, Opscode, Inc. 6 | # 7 | # Licensed under the Apache License, Version 2.0 (the "License"); 8 | # you may not use this file except in compliance with the License. 9 | # You may obtain a copy of the License at 10 | # 11 | # http://www.apache.org/licenses/LICENSE-2.0 12 | # 13 | # Unless required by applicable law or agreed to in writing, software 14 | # distributed under the License is distributed on an "AS IS" BASIS, 15 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | # See the License for the specific language governing permissions and 17 | # limitations under the License. 18 | # 19 | -------------------------------------------------------------------------------- /test/cookbooks/rabbitmq_test/files/default/tests/minitest/ssl_test.rb: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2012, Opscode, Inc. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | # 16 | 17 | describe 'rabbitmq_test::ssl' do 18 | end 19 | -------------------------------------------------------------------------------- /Gemfile: -------------------------------------------------------------------------------- 1 | source 'https://rubygems.org' 2 | 3 | group :lint do 4 | gem 'foodcritic', '~> 3.0' 5 | gem 'rubocop', '~> 0.18' 6 | gem 'rainbow', '< 2.0' 7 | end 8 | 9 | group :unit do 10 | gem 'berkshelf', '~> 3.0.0.beta6' 11 | gem 'chefspec', '~> 3.1' 12 | end 13 | 14 | group :kitchen_common do 15 | gem 'test-kitchen', '~> 1.2' 16 | end 17 | 18 | group :kitchen_vagrant do 19 | gem 'kitchen-vagrant', '~> 0.11' 20 | end 21 | 22 | group :kitchen_cloud do 23 | gem 'kitchen-digitalocean' 24 | gem 'kitchen-ec2' 25 | end 26 | 27 | group :development do 28 | gem 'ruby_gntp' 29 | gem 'growl' 30 | gem 'rb-fsevent' 31 | gem 'guard', '~> 2.4' 32 | gem 'guard-kitchen' 33 | gem 'guard-foodcritic' 34 | gem 'guard-rspec' 35 | gem 'guard-rubocop' 36 | gem 'rake' 37 | end 38 | -------------------------------------------------------------------------------- /templates/default/rabbitmq.upstart.conf.erb: -------------------------------------------------------------------------------- 1 | description "Start rabbitmq on startup" 2 | start on started networking 3 | limit nofile <%= @max_file_descriptors %> <%= @max_file_descriptors %> 4 | 5 | respawn 6 | respawn limit 5 60 7 | 8 | env HOME="" 9 | env RABBITMQ_PID_FILE="/var/run/rabbitmq/pid" 10 | 11 | pre-start script 12 | PID_DIR=`dirname ${RABBITMQ_PID_FILE}` 13 | 14 | if [ ! -d ${PID_DIR} ]; 15 | then 16 | mkdir -p ${PID_DIR} 17 | chown -R rabbitmq:rabbitmq ${PID_DIR} 18 | chmod 755 ${PID_DIR} 19 | fi 20 | end script 21 | 22 | exec /usr/sbin/rabbitmq-server > /var/log/rabbitmq/startup_log \ 23 | 2> /var/log/rabbitmq/startup_err 24 | 25 | post-start exec /usr/sbin/rabbitmqctl wait $RABBITMQ_PID_FILE >/dev/null 2>&1 26 | -------------------------------------------------------------------------------- /resources/plugin.rb: -------------------------------------------------------------------------------- 1 | # 2 | # Cookbook Name:: rabbitmq 3 | # Resource:: plugin 4 | # 5 | # Copyright 2011, Opscode, Inc. 6 | # 7 | # Licensed under the Apache License, Version 2.0 (the "License"); 8 | # you may not use this file except in compliance with the License. 9 | # You may obtain a copy of the License at 10 | # 11 | # http://www.apache.org/licenses/LICENSE-2.0 12 | # 13 | # Unless required by applicable law or agreed to in writing, software 14 | # distributed under the License is distributed on an "AS IS" BASIS, 15 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | # See the License for the specific language governing permissions and 17 | # limitations under the License. 18 | # 19 | 20 | actions :enable, :disable 21 | default_action :enable 22 | 23 | attribute :plugin, :kind_of => String, :name_attribute => true 24 | -------------------------------------------------------------------------------- /test/cookbooks/rabbitmq_test/recipes/cluster.rb: -------------------------------------------------------------------------------- 1 | # 2 | # Cookbook Name:: rabbitmq_test 3 | # Recipe:: cluster 4 | # 5 | # Copyright 2012, Opscode, Inc. 6 | # 7 | # Licensed under the Apache License, Version 2.0 (the "License"); 8 | # you may not use this file except in compliance with the License. 9 | # You may obtain a copy of the License at 10 | # 11 | # http://www.apache.org/licenses/LICENSE-2.0 12 | # 13 | # Unless required by applicable law or agreed to in writing, software 14 | # distributed under the License is distributed on an "AS IS" BASIS, 15 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | # See the License for the specific language governing permissions and 17 | # limitations under the License. 18 | # 19 | 20 | node.set['rabbitmq']['cluster'] = true 21 | include_recipe 'rabbitmq::default' 22 | -------------------------------------------------------------------------------- /resources/vhost.rb: -------------------------------------------------------------------------------- 1 | # 2 | # Cookbook Name:: rabbitmq 3 | # Resource:: vhost 4 | # 5 | # Copyright 2011, Opscode, Inc. 6 | # 7 | # Licensed under the Apache License, Version 2.0 (the "License"); 8 | # you may not use this file except in compliance with the License. 9 | # You may obtain a copy of the License at 10 | # 11 | # http://www.apache.org/licenses/LICENSE-2.0 12 | # 13 | # Unless required by applicable law or agreed to in writing, software 14 | # distributed under the License is distributed on an "AS IS" BASIS, 15 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | # See the License for the specific language governing permissions and 17 | # limitations under the License. 18 | # 19 | 20 | actions :add, :delete 21 | 22 | attribute :vhost, :kind_of => String, :name_attribute => true 23 | 24 | def initialize(*args) 25 | super 26 | @action = :add 27 | end 28 | -------------------------------------------------------------------------------- /resources/policy.rb: -------------------------------------------------------------------------------- 1 | # 2 | # Cookbook Name:: rabbitmq 3 | # Resource:: policy 4 | # 5 | # Author: Robert Choi 6 | # Copyright 2013 by Robert Choi 7 | # 8 | # Licensed under the Apache License, Version 2.0 (the "License"); 9 | # you may not use this file except in compliance with the License. 10 | # You may obtain a copy of the License at 11 | # 12 | # http://www.apache.org/licenses/LICENSE-2.0 13 | # 14 | # Unless required by applicable law or agreed to in writing, software 15 | # distributed under the License is distributed on an "AS IS" BASIS, 16 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 17 | # See the License for the specific language governing permissions and 18 | # limitations under the License. 19 | # 20 | 21 | actions :set, :clear, :list 22 | default_action :set 23 | 24 | attribute :policy, :kind_of => String, :name_attribute => true 25 | attribute :pattern, :kind_of => String 26 | attribute :params, :kind_of => Hash 27 | attribute :priority, :kind_of => Integer 28 | attribute :vhost, :kind_of => String 29 | -------------------------------------------------------------------------------- /recipes/mgmt_console.rb: -------------------------------------------------------------------------------- 1 | # 2 | # Cookbook Name:: rabbitmq 3 | # Recipe:: mgmt_console 4 | # 5 | # Copyright 2012, Tacit Knowledge, Inc. 6 | # 7 | # Licensed under the Apache License, Version 2.0 (the "License"); 8 | # you may not use this file except in compliance with the License. 9 | # You may obtain a copy of the License at 10 | # 11 | # http://www.apache.org/licenses/LICENSE-2.0 12 | # 13 | # Unless required by applicable law or agreed to in writing, software 14 | # distributed under the License is distributed on an "AS IS" BASIS, 15 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | # See the License for the specific language governing permissions and 17 | # limitations under the License. 18 | # 19 | 20 | include_recipe 'rabbitmq::default' 21 | 22 | plugins = %w( rabbitmq_management rabbitmq_management_visualiser ) 23 | 24 | service_name = node['rabbitmq']['service_name'] 25 | 26 | plugins.each do |plugin| 27 | rabbitmq_plugin plugin do 28 | action :enable 29 | notifies :restart, "service[#{service_name}]" 30 | end 31 | end 32 | -------------------------------------------------------------------------------- /test/cookbooks/rabbitmq_test/files/default/tests/minitest/cluster_test.rb: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2012, Opscode, Inc. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | # 16 | 17 | describe 'rabbitmq_test::cluster' do 18 | 19 | it 'writes the erlang cookie file' do 20 | file('/var/lib/rabbitmq/.erlang.cookie').must_exist 21 | end 22 | 23 | it 'writes cluster configuration to the config file' do 24 | file('/etc/rabbitmq/rabbitmq.conf').must_match( 25 | /^ {cluster_nodes, [.*]},$/ 26 | ) 27 | end 28 | 29 | end 30 | -------------------------------------------------------------------------------- /test/cookbooks/rabbitmq_test/recipes/default.rb: -------------------------------------------------------------------------------- 1 | # 2 | # Cookbook Name:: rabbitmq_test 3 | # Recipe:: default 4 | # 5 | # Copyright 2012-2013, Opscode, Inc. 6 | # 7 | # Licensed under the Apache License, Version 2.0 (the "License"); 8 | # you may not use this file except in compliance with the License. 9 | # You may obtain a copy of the License at 10 | # 11 | # http://www.apache.org/licenses/LICENSE-2.0 12 | # 13 | # Unless required by applicable law or agreed to in writing, software 14 | # distributed under the License is distributed on an "AS IS" BASIS, 15 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | # See the License for the specific language governing permissions and 17 | # limitations under the License. 18 | # 19 | 20 | chef_gem 'bunny' 21 | 22 | include_recipe 'rabbitmq::default' 23 | 24 | # HACK: Give rabbit time to spin up before the tests, it seems 25 | # to be responding that it has started before it really has 26 | execute 'sleep 10' do 27 | action :nothing 28 | subscribes :run, "service[#{node['rabbitmq']['service_name']}]", :delayed 29 | end 30 | -------------------------------------------------------------------------------- /test/cookbooks/rabbitmq_test/recipes/mgmt_console.rb: -------------------------------------------------------------------------------- 1 | # 2 | # Cookbook Name:: rabbitmq_test 3 | # Recipe:: mgmt_console 4 | # 5 | # Copyright 2012-2013, Opscode, Inc. 6 | # 7 | # Licensed under the Apache License, Version 2.0 (the "License"); 8 | # you may not use this file except in compliance with the License. 9 | # You may obtain a copy of the License at 10 | # 11 | # http://www.apache.org/licenses/LICENSE-2.0 12 | # 13 | # Unless required by applicable law or agreed to in writing, software 14 | # distributed under the License is distributed on an "AS IS" BASIS, 15 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | # See the License for the specific language governing permissions and 17 | # limitations under the License. 18 | # 19 | 20 | chef_gem 'bunny' 21 | 22 | include_recipe 'rabbitmq::mgmt_console' 23 | 24 | # HACK: Give rabbit time to spin up before the tests, it seems 25 | # to be responding that it has started before it really has 26 | execute 'sleep 10' do 27 | action :nothing 28 | subscribes :run, "service[#{node['rabbitmq']['service_name']}]", :delayed 29 | end 30 | -------------------------------------------------------------------------------- /resources/user.rb: -------------------------------------------------------------------------------- 1 | # 2 | # Cookbook Name:: rabbitmq 3 | # Resource:: user 4 | # 5 | # Copyright 2011-2013, Opscode, Inc. 6 | # 7 | # Licensed under the Apache License, Version 2.0 (the "License"); 8 | # you may not use this file except in compliance with the License. 9 | # You may obtain a copy of the License at 10 | # 11 | # http://www.apache.org/licenses/LICENSE-2.0 12 | # 13 | # Unless required by applicable law or agreed to in writing, software 14 | # distributed under the License is distributed on an "AS IS" BASIS, 15 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | # See the License for the specific language governing permissions and 17 | # limitations under the License. 18 | # 19 | 20 | actions :add, :delete, :set_permissions, :clear_permissions, :set_tags, :clear_tags, :change_password 21 | 22 | attribute :user, :kind_of => String, :name_attribute => true 23 | attribute :password, :kind_of => String 24 | attribute :vhost, :kind_of => String 25 | attribute :permissions, :kind_of => String 26 | attribute :tag, :kind_of => String 27 | 28 | def initialize(*args) 29 | super 30 | @action = :add 31 | end 32 | -------------------------------------------------------------------------------- /Guardfile: -------------------------------------------------------------------------------- 1 | # A sample Guardfile 2 | # More info at https://github.com/guard/guard#readme 3 | 4 | # guard 'kitchen' do 5 | # watch(%r{test/.+}) 6 | # watch(%r{^recipes/(.+)\.rb$}) 7 | # watch(%r{^attributes/(.+)\.rb$}) 8 | # watch(%r{^files/(.+)}) 9 | # watch(%r{^templates/(.+)}) 10 | # watch(%r{^providers/(.+)\.rb}) 11 | # watch(%r{^resources/(.+)\.rb}) 12 | # end 13 | 14 | guard 'foodcritic', cookbook_paths: '.', all_on_start: false do 15 | watch(%r{attributes/.+\.rb$}) 16 | watch(%r{providers/.+\.rb$}) 17 | watch(%r{recipes/.+\.rb$}) 18 | watch(%r{resources/.+\.rb$}) 19 | watch('metadata.rb') 20 | end 21 | 22 | guard 'rubocop', all_on_start: false do 23 | watch(%r{attributes/.+\.rb$}) 24 | watch(%r{providers/.+\.rb$}) 25 | watch(%r{recipes/.+\.rb$}) 26 | watch(%r{resources/.+\.rb$}) 27 | watch('metadata.rb') 28 | end 29 | 30 | guard :rspec, cmd: 'bundle exec rspec', all_on_start: false, notification: false do 31 | watch(%r{^libraries/(.+)\.rb$}) 32 | watch(%r{^spec/(.+)_spec\.rb$}) 33 | watch(%r{^(recipes)/(.+)\.rb$}) { |m| "spec/#{m[1]}_spec.rb" } 34 | watch('spec/spec_helper.rb') { 'spec' } 35 | end 36 | -------------------------------------------------------------------------------- /test/cookbooks/rabbitmq_test/files/default/tests/minitest/mgmt_console_test.rb: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2012-2013, Opscode, Inc. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | # 16 | 17 | require File.expand_path('../support/helpers', __FILE__) 18 | 19 | describe 'rabbitmq_test::mgmt_console' do 20 | include Helpers::RabbitMQ 21 | 22 | it 'enables the rabbitmq_management plugin' do 23 | assert(plugin_enabled?('rabbitmq_management')) 24 | end 25 | 26 | it 'enables the rabbitmq_management_visualiser plugin' do 27 | assert(plugin_enabled?('rabbitmq_management_visualiser')) 28 | end 29 | 30 | end 31 | -------------------------------------------------------------------------------- /test/cookbooks/rabbitmq_test/files/default/tests/minitest/cook-1724_test.rb: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2012, Opscode, Inc. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | # 16 | 17 | describe 'rabbitmq_test::cook-1724' do 18 | include MiniTest::Chef::Assertions 19 | include MiniTest::Chef::Context 20 | include MiniTest::Chef::Resources 21 | 22 | it 'doesnt use the rabbitmq apt repository' do 23 | skip 'Only applicable on Debian family' unless node['platform_family'] == 'debian' 24 | 25 | file('/etc/apt/sources.list.d/rabbitmq-source.list').wont_exist && 26 | package('rabbitmq-server').must_be_installed 27 | end 28 | 29 | end 30 | -------------------------------------------------------------------------------- /templates/default/rabbitmq-env.conf.erb: -------------------------------------------------------------------------------- 1 | ### 2 | # Generated by Chef 3 | ### 4 | 5 | <% if node['rabbitmq']['local_erl_networking'] -%> 6 | NODENAME=rabbit@localhost 7 | NODE_IP_ADDRESS=127.0.0.1 8 | export ERL_EPMD_ADDRESS=127.0.0.1 9 | <% elsif node['rabbitmq']['erl_networking_bind_address'] -%> 10 | NODENAME=<%= node['rabbitmq']['nodename'] %> 11 | NODE_IP_ADDRESS=<%= node['rabbitmq']['erl_networking_bind_address'] %> 12 | export ERL_EPMD_ADDRESS=<%= node['rabbitmq']['erl_networking_bind_address'] %> 13 | <% else -%> 14 | <% if node['rabbitmq']['address'] -%>NODE_IP_ADDRESS=<%= node['rabbitmq']['address'] %><% end %> 15 | <% if node['rabbitmq']['nodename'] -%>NODENAME=<%= node['rabbitmq']['nodename'] %><% end %> 16 | <% end -%> 17 | <% if node['rabbitmq']['port'] -%>NODE_PORT=<%= node['rabbitmq']['port'] %><% end %> 18 | <% if node['rabbitmq']['config'] -%>CONFIG_FILE=<%= node['rabbitmq']['config'] %><% end %> 19 | <% if node['rabbitmq']['logdir'] -%>LOG_BASE=<%= node['rabbitmq']['logdir'] %><% end %> 20 | <% if node['rabbitmq']['mnesiadir'] -%>MNESIA_BASE=<%= node['rabbitmq']['mnesiadir'] %><% end %> 21 | 22 | <% if node['rabbitmq']['open_file_limit'] -%>ulimit -n <%= node['rabbitmq']['open_file_limit'] %><% end %> 23 | -------------------------------------------------------------------------------- /recipes/plugin_management.rb: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # 3 | # Cookbook Name:: rabbitmq 4 | # Recipe:: plugin_management 5 | # 6 | # Copyright 2013, Grégoire Seux 7 | # Copyright 2013, Opscode, Inc. 8 | # 9 | # Licensed under the Apache License, Version 2.0 (the "License"); 10 | # you may not use this file except in compliance with the License. 11 | # You may obtain a copy of the License at 12 | # 13 | # http://www.apache.org/licenses/LICENSE-2.0 14 | # 15 | # Unless required by applicable law or agreed to in writing, software 16 | # distributed under the License is distributed on an "AS IS" BASIS, 17 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 18 | # See the License for the specific language governing permissions and 19 | # limitations under the License. 20 | # 21 | 22 | include_recipe 'rabbitmq::default' 23 | 24 | node['rabbitmq']['enabled_plugins'].each do |plugin| 25 | rabbitmq_plugin plugin do 26 | action :enable 27 | notifies :restart, "service[#{node['rabbitmq']['service_name']}]" 28 | end 29 | end 30 | 31 | node['rabbitmq']['disabled_plugins'].each do |plugin| 32 | rabbitmq_plugin plugin do 33 | action :disable 34 | notifies :restart, "service[#{node['rabbitmq']['service_name']}]" 35 | end 36 | end 37 | -------------------------------------------------------------------------------- /recipes/virtualhost_management.rb: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # 3 | # Cookbook Name:: rabbitmq 4 | # Recipe:: virtualhost_management 5 | # 6 | # Copyright 2013, Grégoire Seux 7 | # Copyright 2013, Opscode, Inc. 8 | # 9 | # Licensed under the Apache License, Version 2.0 (the "License"); 10 | # you may not use this file except in compliance with the License. 11 | # You may obtain a copy of the License at 12 | # 13 | # http://www.apache.org/licenses/LICENSE-2.0 14 | # 15 | # Unless required by applicable law or agreed to in writing, software 16 | # distributed under the License is distributed on an "AS IS" BASIS, 17 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 18 | # See the License for the specific language governing permissions and 19 | # limitations under the License. 20 | # 21 | 22 | include_recipe 'rabbitmq::default' 23 | 24 | node['rabbitmq']['virtualhosts'].each do |virtualhost| 25 | rabbitmq_vhost virtualhost do 26 | action :add 27 | notifies :restart, "service[#{node['rabbitmq']['service_name']}]" 28 | end 29 | end 30 | 31 | node['rabbitmq']['disabled_virtualhosts'].each do |virtualhost| 32 | rabbitmq_vhost virtualhost do 33 | action :delete 34 | notifies :restart, "service[#{node['rabbitmq']['service_name']}]" 35 | end 36 | end 37 | -------------------------------------------------------------------------------- /recipes/policy_management.rb: -------------------------------------------------------------------------------- 1 | # 2 | # Cookbook Name:: rabbitmq 3 | # Recipe:: policy_management 4 | # 5 | # Author: Robert Choi 6 | # Copyright 2013 by Robert Choi 7 | # Copyright 2013, Opscode, Inc. 8 | # 9 | # Licensed under the Apache License, Version 2.0 (the "License"); 10 | # you may not use this file except in compliance with the License. 11 | # You may obtain a copy of the License at 12 | # 13 | # http://www.apache.org/licenses/LICENSE-2.0 14 | # 15 | # Unless required by applicable law or agreed to in writing, software 16 | # distributed under the License is distributed on an "AS IS" BASIS, 17 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 18 | # See the License for the specific language governing permissions and 19 | # limitations under the License. 20 | # 21 | 22 | include_recipe 'rabbitmq::default' 23 | 24 | node['rabbitmq']['policies'].each do |name, policy| 25 | rabbitmq_policy name do 26 | pattern policy['pattern'] 27 | params policy['params'] 28 | priority policy['priority'] 29 | vhost policy['vhost'] 30 | action :set 31 | notifies :restart, "service[#{node['rabbitmq']['service_name']}]" 32 | end 33 | end 34 | 35 | node['rabbitmq']['disabled_policies'].each do |policy| 36 | rabbitmq_policy policy do 37 | action :clear 38 | notifies :restart, "service[#{node['rabbitmq']['service_name']}]" 39 | end 40 | end 41 | -------------------------------------------------------------------------------- /test/cookbooks/rabbitmq_test/recipes/lwrps.rb: -------------------------------------------------------------------------------- 1 | # 2 | # Cookbook Name:: rabbitmq_test 3 | # Recipe:: lwrps 4 | # 5 | # Copyright 2013, Opscode, Inc. 6 | # 7 | # Licensed under the Apache License, Version 2.0 (the "License"); 8 | # you may not use this file except in compliance with the License. 9 | # You may obtain a copy of the License at 10 | # 11 | # http://www.apache.org/licenses/LICENSE-2.0 12 | # 13 | # Unless required by applicable law or agreed to in writing, software 14 | # distributed under the License is distributed on an "AS IS" BASIS, 15 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | # See the License for the specific language governing permissions and 17 | # limitations under the License. 18 | # 19 | 20 | chef_gem 'bunny' 21 | 22 | include_recipe 'rabbitmq::default' 23 | 24 | # force the rabbitmq restart now, then start testing 25 | execute 'sleep 10' do 26 | notifies :restart, "service[#{node['rabbitmq']['service_name']}]", :immediately 27 | end 28 | 29 | include_recipe 'rabbitmq::plugin_management' 30 | include_recipe 'rabbitmq::virtualhost_management' 31 | include_recipe 'rabbitmq::policy_management' 32 | include_recipe 'rabbitmq::user_management' 33 | 34 | # can't verify it actually goes through without logging in, but at least exercise the code 35 | rabbitmq_user 'kitchen3' do 36 | password 'foobar' 37 | action :change_password 38 | end 39 | -------------------------------------------------------------------------------- /recipes/user_management.rb: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # 3 | # Cookbook Name:: rabbitmq 4 | # Recipe:: user_management 5 | # 6 | # Copyright 2013, Grégoire Seux 7 | # Copyright 2013, Opscode, Inc. 8 | # 9 | # Licensed under the Apache License, Version 2.0 (the "License"); 10 | # you may not use this file except in compliance with the License. 11 | # You may obtain a copy of the License at 12 | # 13 | # http://www.apache.org/licenses/LICENSE-2.0 14 | # 15 | # Unless required by applicable law or agreed to in writing, software 16 | # distributed under the License is distributed on an "AS IS" BASIS, 17 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 18 | # See the License for the specific language governing permissions and 19 | # limitations under the License. 20 | # 21 | 22 | include_recipe 'rabbitmq::default' 23 | include_recipe 'rabbitmq::virtualhost_management' 24 | 25 | node['rabbitmq']['enabled_users'].each do |user| 26 | rabbitmq_user user['name'] do 27 | password user['password'] 28 | action :add 29 | end 30 | rabbitmq_user user['name'] do 31 | tag user['tag'] 32 | action :set_tags 33 | end 34 | user['rights'].each do |r| 35 | rabbitmq_user user['name'] do 36 | vhost r['vhost'] 37 | permissions "#{r['conf']} #{r['write']} #{r['read']}" 38 | action :set_permissions 39 | end 40 | end 41 | end 42 | 43 | node['rabbitmq']['disabled_users'].each do |user| 44 | rabbitmq_user user do 45 | action :delete 46 | end 47 | end 48 | -------------------------------------------------------------------------------- /test/cookbooks/rabbitmq_test/files/default/tests/minitest/cook-2151-3489_test.rb: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2012-2013, Opscode, Inc. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | # 16 | 17 | require File.expand_path('../support/helpers', __FILE__) 18 | 19 | describe 'rabbitmq_test::cook-2151' do 20 | include Helpers::RabbitMQ 21 | 22 | it 'includes the disk_free_limit configuration setting' do 23 | file("#{node['rabbitmq']['config_root']}/rabbitmq.config") 24 | .must_match(/\{disk_free_limit, \{mem_relative, #{node['rabbitmq']['disk_free_limit_relative']}/) 25 | end 26 | 27 | it 'includes the vm_memory_high_watermark configuration setting' do 28 | file("#{node['rabbitmq']['config_root']}/rabbitmq.config") 29 | .must_match(/\{vm_memory_high_watermark, #{node['rabbitmq']['vm_memory_high_watermark']}/) 30 | end 31 | 32 | it 'includes the open_file_limit configuration setting' do 33 | file("#{node['rabbitmq']['config_root']}/rabbitmq-env.conf") 34 | .must_match(/(ulimit -n #{node['rabbitmq']['open_file_limit']})/) 35 | end 36 | 37 | end 38 | -------------------------------------------------------------------------------- /test/cookbooks/rabbitmq_test/files/default/tests/minitest/cook-1684_test.rb: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2012, Opscode, Inc. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | # 16 | 17 | describe 'rabbitmq_test::cook-1684' do 18 | include MiniTest::Chef::Assertions 19 | include MiniTest::Chef::Context 20 | include MiniTest::Chef::Resources 21 | 22 | it 'installs rabbitmq from deb file when apt isnt used' do 23 | skip 'Only applicable on Debian family' unless node['platform_family'] == 'debian' 24 | 25 | file("#{Chef::Config[:file_cache_path]}/rabbitmq-server_#{node['rabbitmq']['version']}-1_all.deb").must_exist && 26 | package('rabbitmq-server').must_be_installed 27 | end 28 | 29 | it 'installs rabbitmq from yum when used' do 30 | skip 'Only applicable on RHEL/Fedora family' unless node['platform_family'] == 'rhel' || node['platform_family'] == 'fedora' 31 | 32 | rpm_path = "#{Chef::Config[:file_cache_path]}/rabbitmq-server-#{node['rabbitmq']['version']}-1.noarch.rpm" 33 | 34 | file(rpm_path).wont_exist && package('rabbitmq-server').must_be_installed 35 | end 36 | 37 | end 38 | -------------------------------------------------------------------------------- /test/cookbooks/rabbitmq_test/files/default/tests/minitest/support/helpers.rb: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2012-2013, Opscode, Inc. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | # 16 | 17 | module Helpers 18 | # rabbitmq 19 | module RabbitMQ 20 | require 'mixlib/shellout' 21 | include MiniTest::Chef::Assertions 22 | include MiniTest::Chef::Context 23 | include MiniTest::Chef::Resources 24 | 25 | def plugin_enabled?(plugin) 26 | plugins = Mixlib::ShellOut.new("rabbitmq-plugins list -e '#{plugin}'").run_command 27 | plugins.stdout =~ /(\[[Ee]\]\s#{plugin})/ 28 | end 29 | 30 | def policy_enabled?(policy) 31 | policies = Mixlib::ShellOut.new('rabbitmqctl -q list_policies').run_command 32 | policies.stdout =~ /\t#{policy}\t/ 33 | end 34 | 35 | def user_enabled?(user) 36 | users = Mixlib::ShellOut.new('rabbitmqctl -q list_users').run_command 37 | users.stdout =~ /(#{user}\s)/ 38 | end 39 | 40 | def vhost_enabled?(vhost) 41 | vhosts = Mixlib::ShellOut.new('rabbitmqctl -q list_vhosts').run_command 42 | vhosts.stdout =~ /(\n#{vhost}\n)/ 43 | end 44 | end 45 | end 46 | -------------------------------------------------------------------------------- /libraries/default.rb: -------------------------------------------------------------------------------- 1 | # 2 | # Cookbook Name:: rabbitmq 3 | # Library:: default 4 | # Author:: Jake Davis () 5 | # 6 | # Licensed under the Apache License, Version 2.0 (the "License"); 7 | # you may not use this file except in compliance with the License. 8 | # You may obtain a copy of the License at 9 | # 10 | # http://www.apache.org/licenses/LICENSE-2.0 11 | # 12 | # Unless required by applicable law or agreed to in writing, software 13 | # distributed under the License is distributed on an "AS IS" BASIS, 14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | # See the License for the specific language governing permissions and 16 | # limitations under the License. 17 | # 18 | 19 | module Opscode 20 | # module rabbit 21 | module RabbitMQ 22 | # This method does some of the yuckiness of formatting parameters properly 23 | # for rendering into the rabbit.config template. 24 | def format_kernel_parameters 25 | rendered = [] 26 | kernel = node['rabbitmq']['kernel'].dup 27 | 28 | # This parameter is special and needs commas instead of periods. 29 | rendered << "{inet_dist_use_interface, {#{kernel[:inet_dist_use_interface].gsub(/\./, ',')}}}" if kernel[:inet_dist_use_interface] 30 | kernel.delete(:inet_dist_use_interface) 31 | 32 | # Otherwise, we can just render it nicely as Erlang wants. This 33 | # theoretically opens the door for arbitrary kernel_app parameters to be 34 | # declared. 35 | kernel.select { |k, v| !v.nil? }.each_pair do |param, val| 36 | rendered << "{#{param}, #{val}}" 37 | end 38 | 39 | rendered.each { |r| r.prepend(' ') }.join(",\n") 40 | end 41 | end 42 | end 43 | -------------------------------------------------------------------------------- /Rakefile: -------------------------------------------------------------------------------- 1 | require 'rspec/core/rake_task' 2 | require 'rubocop/rake_task' 3 | require 'foodcritic' 4 | require 'kitchen' 5 | 6 | # Style tests. Rubocop and Foodcritic 7 | namespace :style do 8 | desc 'Run Ruby style checks' 9 | Rubocop::RakeTask.new(:ruby) 10 | 11 | desc 'Run Chef style checks' 12 | FoodCritic::Rake::LintTask.new(:chef) do |t| 13 | t.options = { 14 | fail_tags: ['any'], 15 | tags: [ 16 | '~FC005', 17 | '~FC023' 18 | ] 19 | } 20 | end 21 | end 22 | 23 | desc 'Run all style checks' 24 | task style: ['style:chef', 'style:ruby'] 25 | 26 | # Rspec and ChefSpec 27 | desc "Run ChefSpec examples" 28 | RSpec::Core::RakeTask.new(:spec) 29 | 30 | # Integration tests. Kitchen.ci 31 | namespace :integration do 32 | desc 'Run Test Kitchen with Vagrant' 33 | task :vagrant do 34 | Kitchen.logger = Kitchen.default_file_logger 35 | Kitchen::Config.new.instances.each do |instance| 36 | instance.test(:always) 37 | end 38 | end 39 | 40 | desc 'Run Test Kitchen with cloud plugins' 41 | task :cloud do 42 | run_kitchen = true 43 | if ENV['TRAVIS'] == 'true' && ENV['TRAVIS_PULL_REQUEST'] != 'false' 44 | run_kitchen = false 45 | end 46 | 47 | if run_kitchen 48 | Kitchen.logger = Kitchen.default_file_logger 49 | @loader = Kitchen::Loader::YAML.new(project_config: './.kitchen.cloud.yml') 50 | config = Kitchen::Config.new( loader: @loader) 51 | config.instances.each do |instance| 52 | instance.test(:always) 53 | end 54 | end 55 | end 56 | end 57 | 58 | desc 'Run all tests on Travis' 59 | task travis: ['style', 'spec', 'integration:cloud'] 60 | 61 | # Default 62 | task default: ['style', 'spec', 'integration:vagrant'] 63 | -------------------------------------------------------------------------------- /providers/vhost.rb: -------------------------------------------------------------------------------- 1 | # 2 | # Cookbook Name:: rabbitmq 3 | # Provider:: vhost 4 | # 5 | # Copyright 2011-2013, Opscode, Inc. 6 | # 7 | # Licensed under the Apache License, Version 2.0 (the "License"); 8 | # you may not use this file except in compliance with the License. 9 | # You may obtain a copy of the License at 10 | # 11 | # http://www.apache.org/licenses/LICENSE-2.0 12 | # 13 | # Unless required by applicable law or agreed to in writing, software 14 | # distributed under the License is distributed on an "AS IS" BASIS, 15 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | # See the License for the specific language governing permissions and 17 | # limitations under the License. 18 | # 19 | 20 | def vhost_exists?(name) 21 | cmd = "rabbitmqctl -q list_vhosts | grep ^#{name}$" 22 | cmd = Mixlib::ShellOut.new(cmd) 23 | cmd.environment['HOME'] = ENV.fetch('HOME', '/root') 24 | cmd.run_command 25 | Chef::Log.debug "rabbitmq_vhost_exists?: #{cmd}" 26 | Chef::Log.debug "rabbitmq_vhost_exists?: #{cmd.stdout}" 27 | begin 28 | cmd.error! 29 | true 30 | rescue 31 | false 32 | end 33 | end 34 | 35 | action :add do 36 | unless vhost_exists?(new_resource.vhost) 37 | cmd = "rabbitmqctl add_vhost #{new_resource.vhost}" 38 | execute cmd do 39 | Chef::Log.debug "rabbitmq_vhost_add: #{cmd}" 40 | Chef::Log.info "Adding RabbitMQ vhost '#{new_resource.vhost}'." 41 | new_resource.updated_by_last_action(true) 42 | end 43 | end 44 | end 45 | 46 | action :delete do 47 | if vhost_exists?(new_resource.vhost) 48 | cmd = "rabbitmqctl delete_vhost #{new_resource.vhost}" 49 | execute cmd do 50 | Chef::Log.debug "rabbitmq_vhost_delete: #{cmd}" 51 | Chef::Log.info "Deleting RabbitMQ vhost '#{new_resource.vhost}'." 52 | new_resource.updated_by_last_action(true) 53 | end 54 | end 55 | end 56 | -------------------------------------------------------------------------------- /providers/plugin.rb: -------------------------------------------------------------------------------- 1 | # 2 | # Cookbook Name:: rabbitmq 3 | # Provider:: plugin 4 | # 5 | # Copyright 2012-2013, Opscode, Inc. 6 | # 7 | # Licensed under the Apache License, Version 2.0 (the "License"); 8 | # you may not use this file except in compliance with the License. 9 | # You may obtain a copy of the License at 10 | # 11 | # http://www.apache.org/licenses/LICENSE-2.0 12 | # 13 | # Unless required by applicable law or agreed to in writing, software 14 | # distributed under the License is distributed on an "AS IS" BASIS, 15 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | # See the License for the specific language governing permissions and 17 | # limitations under the License. 18 | # 19 | 20 | def plugins_bin_path(return_array = false) 21 | path = ENV.fetch('PATH') + ':/usr/lib/rabbitmq/bin' 22 | return_array ? path.split(':') : path 23 | end 24 | 25 | def plugin_enabled?(name) 26 | cmdstr = "rabbitmq-plugins list -e '#{name}\\b'" 27 | cmd = Mixlib::ShellOut.new(cmdstr) 28 | cmd.environment['HOME'] = ENV.fetch('HOME', '/root') 29 | cmd.environment['PATH'] = plugins_bin_path 30 | cmd.run_command 31 | Chef::Log.debug "rabbitmq_plugin_enabled?: #{cmdstr}" 32 | Chef::Log.debug "rabbitmq_plugin_enabled?: #{cmd.stdout}" 33 | cmd.error! 34 | cmd.stdout =~ /\b#{name}\b/ 35 | end 36 | 37 | action :enable do 38 | unless plugin_enabled?(new_resource.plugin) 39 | execute "rabbitmq-plugins enable #{new_resource.plugin}" do 40 | Chef::Log.info "Enabling RabbitMQ plugin '#{new_resource.plugin}'." 41 | path plugins_bin_path(true) 42 | new_resource.updated_by_last_action(true) 43 | end 44 | end 45 | end 46 | 47 | action :disable do 48 | if plugin_enabled?(new_resource.plugin) 49 | execute "rabbitmq-plugins disable #{new_resource.plugin}" do 50 | Chef::Log.info "Disabling RabbitMQ plugin '#{new_resource.plugin}'." 51 | path plugins_bin_path(true) 52 | new_resource.updated_by_last_action(true) 53 | end 54 | end 55 | end 56 | -------------------------------------------------------------------------------- /test/cookbooks/rabbitmq_test/files/default/tests/minitest/lwrps_test.rb: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2013, Opscode, Inc. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | # 16 | 17 | require File.expand_path('../support/helpers', __FILE__) 18 | 19 | describe 'rabbitmq_test::lwrps' do 20 | include Helpers::RabbitMQ 21 | 22 | # plugins 23 | it 'enabled the rabbitmq_stomp plugin' do 24 | assert(plugin_enabled?('rabbitmq_stomp')) 25 | end 26 | 27 | it 'disabled the nonexistant_plugin and rabbitmq_shovel plugin' do 28 | assert(!plugin_enabled?('rabbitmq_shovel')) 29 | assert(!plugin_enabled?('nonexistant_plugin')) 30 | end 31 | 32 | # users 33 | it 'enabled the kitchen1 and kitchen3 users' do 34 | assert(user_enabled?('kitchen1')) 35 | assert(user_enabled?('kitchen3')) 36 | end 37 | 38 | it 'disabled the nonexistant_user and kitchen2 users' do 39 | assert(!user_enabled?('kitchen2')) 40 | assert(!user_enabled?('nonexistant_user')) 41 | end 42 | 43 | # policies 44 | it 'enabled the example policies from the default attributes' do 45 | assert(policy_enabled?('ha-all')) 46 | assert(policy_enabled?('ha-two')) 47 | end 48 | 49 | it 'disabled the nonexistant_policy' do 50 | assert(!policy_enabled?('nonexistant_policy')) 51 | end 52 | 53 | # vhosts 54 | it 'enabled the kitchen vhost' do 55 | assert(vhost_enabled?('kitchen')) 56 | end 57 | 58 | it 'disabled the nonexistant_vhost' do 59 | assert(!vhost_enabled?('nonexistant_vhost')) 60 | end 61 | end 62 | -------------------------------------------------------------------------------- /libraries/matchers.rb: -------------------------------------------------------------------------------- 1 | if defined?(ChefSpec) 2 | def add_rabbitmq_user(resource_name) 3 | ChefSpec::Matchers::ResourceMatcher.new(:rabbitmq_user, :add, resource_name) 4 | end 5 | 6 | def delete_rabbitmq_user(resource_name) 7 | ChefSpec::Matchers::ResourceMatcher.new(:rabbitmq_user, :delete, resource_name) 8 | end 9 | 10 | def set_permissions_rabbitmq_user(resource_name) # rubocop:disable AccessorMethodName 11 | ChefSpec::Matchers::ResourceMatcher.new(:rabbitmq_user, :set_permissions, resource_name) 12 | end 13 | 14 | def clear_permissions_rabbitmq_user(resource_name) 15 | ChefSpec::Matchers::ResourceMatcher.new(:rabbitmq_user, :clear_permissions, resource_name) 16 | end 17 | 18 | def set_tags_rabbitmq_user(resource_name) # rubocop:disable AccessorMethodName 19 | ChefSpec::Matchers::ResourceMatcher.new(:rabbitmq_user, :set_tags, resource_name) 20 | end 21 | 22 | def clear_tags_rabbitmq_user(resource_name) 23 | ChefSpec::Matchers::ResourceMatcher.new(:rabbitmq_user, :clear_tags, resource_name) 24 | end 25 | 26 | def change_password_rabbitmq_user(resource_name) 27 | ChefSpec::Matchers::ResourceMatcher.new(:rabbitmq_user, :change_password, resource_name) 28 | end 29 | 30 | def add_rabbitmq_vhost(resource_name) 31 | ChefSpec::Matchers::ResourceMatcher.new(:rabbitmq_vhost, :add, resource_name) 32 | end 33 | 34 | def delete_rabbitmq_vhost(resource_name) 35 | ChefSpec::Matchers::ResourceMatcher.new(:rabbitmq_vhost, :delete, resource_name) 36 | end 37 | 38 | def set_rabbitmq_policy(resource_name) # rubocop:disable AccessorMethodName 39 | ChefSpec::Matchers::ResourceMatcher.new(:rabbitmq_policy, :set, resource_name) 40 | end 41 | 42 | def clear_rabbitmq_policy(resource_name) 43 | ChefSpec::Matchers::ResourceMatcher.new(:rabbitmq_policy, :clear, resource_name) 44 | end 45 | 46 | def list_rabbitmq_policy(resource_name) 47 | ChefSpec::Matchers::ResourceMatcher.new(:rabbitmq_policy, :list, resource_name) 48 | end 49 | 50 | def enable_rabbitmq_plugin(resource_name) 51 | ChefSpec::Matchers::ResourceMatcher.new(:rabbitmq_plugin, :enable, resource_name) 52 | end 53 | 54 | def disable_rabbitmq_plugin(resource_name) 55 | ChefSpec::Matchers::ResourceMatcher.new(:rabbitmq_plugin, :disable, resource_name) 56 | end 57 | end 58 | -------------------------------------------------------------------------------- /test/cookbooks/rabbitmq_test/files/default/tests/minitest/default_test.rb: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2012-2013, Opscode, Inc. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | # 16 | 17 | require File.expand_path('../support/helpers', __FILE__) 18 | 19 | describe 'rabbitmq_test::default' do 20 | include Helpers::RabbitMQ 21 | 22 | # packages 23 | it 'installs the rabbitmq-server package' do 24 | if node['rabbitmq']['use_distro_version'] 25 | package('rabbitmq-server').must_be_installed 26 | else 27 | package('rabbitmq-server').must_be_installed.with(:version, '3.1.5-1') 28 | end 29 | end 30 | 31 | # directories 32 | it 'creates the mnesia directory' do 33 | directory(node['rabbitmq']['mnesiadir']).must_have(:mode, '775').with(:owner, 'rabbitmq').and(:group, 'rabbitmq') 34 | end 35 | 36 | # file 37 | it 'has the correct config files' do 38 | file("#{node['rabbitmq']['config_root']}/rabbitmq-env.conf").must_exist.with(:owner, 'root').and(:group, 'root') 39 | file("#{node['rabbitmq']['config_root']}/rabbitmq.config").must_exist.with(:owner, 'root').and(:group, 'root') 40 | end 41 | 42 | # service 43 | it 'enables & starts the rabbitmq-server service' do 44 | service(node['rabbitmq']['service_name']).must_be_enabled unless node['rabbitmq']['job_control'] == 'upstart' 45 | service(node['rabbitmq']['service_name']).must_be_running unless node['rabbitmq']['use_distro_version'] 46 | end 47 | 48 | # accepts connections 49 | it 'accepts AMQP connections' do 50 | unless node['rabbitmq']['use_distro_version'] 51 | require 'bunny' 52 | b = Bunny.new(:host => 'localhost', 53 | :port => 5672, 54 | :user => node['rabbitmq']['default_user'], 55 | :pass => node['rabbitmq']['default_pass']) 56 | b.start 57 | b.stop 58 | end 59 | end 60 | end 61 | -------------------------------------------------------------------------------- /templates/default/rabbitmq.config.erb: -------------------------------------------------------------------------------- 1 | %%% 2 | %% Generated by Chef 3 | %%% 4 | 5 | [ 6 | {kernel, [ 7 | <%= @kernel %> 8 | ]}, 9 | <% if node['rabbitmq']['web_console_ssl'] -%> 10 | {rabbitmq_management, [ 11 | {listener, [{port, <%= node['rabbitmq']['web_console_ssl_port'] %>}, 12 | {ssl, true}, 13 | {ssl_opts, [{cacertfile,"<%= node['rabbitmq']['ssl_cacert'] %>"}, 14 | {certfile,"<%= node['rabbitmq']['ssl_cert'] %>"}, 15 | {keyfile,"<%= node['rabbitmq']['ssl_key'] %>"}]} 16 | ]} 17 | ]}, 18 | <% end %> 19 | {rabbit, [ 20 | <% if node['rabbitmq']['cluster'] && node['rabbitmq']['cluster_disk_nodes'] -%> 21 | {cluster_nodes, {[<%= node['rabbitmq']['cluster_disk_nodes'].map{|n| "\'#{n}\'"}.join(',') %>], disc}}, 22 | {cluster_partition_handling,<%= node['rabbitmq']['cluster_partition_handling'] %>}, 23 | <% end %> 24 | <% if node['rabbitmq']['ssl'] -%> 25 | {ssl_listeners, [<%= node['rabbitmq']['ssl_port'] %>]}, 26 | {ssl_options, [{cacertfile,"<%= node['rabbitmq']['ssl_cacert'] %>"}, 27 | {certfile,"<%= node['rabbitmq']['ssl_cert'] %>"}, 28 | {keyfile,"<%= node['rabbitmq']['ssl_key'] %>"}, 29 | {verify,<%= node['rabbitmq']['ssl_verify'] %>}, 30 | {fail_if_no_peer_cert,<%= node['rabbitmq']['ssl_fail_if_no_peer_cert'] %>}]}, 31 | <% end %> 32 | {tcp_listen_options, [binary, {packet,<%= node['rabbitmq']['tcp_listen_packet'] %>}, 33 | {reuseaddr,<%= node['rabbitmq']['tcp_listen_reuseaddr'] %>}, 34 | {backlog,<%= node['rabbitmq']['tcp_listen_backlog'] %>}, 35 | {nodelay,<%= node['rabbitmq']['tcp_listen_nodelay'] %>}, 36 | {exit_on_close,<%= node['rabbitmq']['tcp_listen_exit_on_close'] %>}, 37 | {keepalive,<%= node['rabbitmq']['tcp_listen_keepalive'] %>}]}, 38 | <% if node['rabbitmq']['disk_free_limit_relative'] -%> 39 | {disk_free_limit, {mem_relative, <%= node['rabbitmq']['disk_free_limit_relative'] %>}}, 40 | <% end %> 41 | <% if node['rabbitmq']['vm_memory_high_watermark'] -%> 42 | {vm_memory_high_watermark, <%= node['rabbitmq']['vm_memory_high_watermark'] %>}, 43 | <% end %> 44 | {default_user, <<"<%= node['rabbitmq']['default_user'] %>">>}, 45 | {default_pass, <<"<%= node['rabbitmq']['default_pass'] %>">>} 46 | ]} 47 | ]. 48 | -------------------------------------------------------------------------------- /.kitchen.cloud.yml: -------------------------------------------------------------------------------- 1 | --- 2 | driver_config: 3 | digitalocean_client_id: <%= ENV['DIGITAL_OCEAN_CLIENT_ID'] %> 4 | digitalocean_api_key: <%= ENV['DIGITAL_OCEAN_API_KEY'] %> 5 | aws_access_key_id: <%= ENV['AWS_ACCESS_KEY_ID'] %> 6 | aws_secret_access_key: <%= ENV['AWS_SECRET_ACCESS_KEY'] %> 7 | aws_ssh_key_id: <%= ENV['AWS_KEYPAIR_NAME'] %> 8 | 9 | provisioner: 10 | name: chef_zero 11 | require_chef_omnibus: latest 12 | 13 | platforms: 14 | - name: centos-5.8 15 | driver_plugin: digitalocean 16 | driver_config: 17 | image_id: 1601 18 | flavor_id: 63 19 | region_id: 4 20 | ssh_key_ids: <%= ENV['DIGITAL_OCEAN_SSH_KEY_IDS'] %> 21 | ssh_key: <%= ENV['DIGITAL_OCEAN_SSH_KEY_PATH'] %> 22 | 23 | - name: centos-6.4 24 | driver_plugin: digitalocean 25 | driver_config: 26 | image_id: 562354 27 | flavor_id: 63 28 | region_id: 4 29 | ssh_key_ids: <%= ENV['DIGITAL_OCEAN_SSH_KEY_IDS'] %> 30 | ssh_key: <%= ENV['DIGITAL_OCEAN_SSH_KEY_PATH'] %> 31 | 32 | - name: amazon-2013.09 33 | driver_plugin: ec2 34 | driver_config: 35 | image_id: ami-3be4bc52 36 | username: ec2-user 37 | ssh_key: <%= ENV['EC2_SSH_KEY_PATH'] %> 38 | 39 | - name: debian-70 40 | driver_plugin: digitalocean 41 | driver_config: 42 | image_id: 308287 43 | flavor_id: 63 44 | region_id: 4 45 | ssh_key_ids: <%= ENV['DIGITAL_OCEAN_SSH_KEY_IDS'] %> 46 | run_list: 47 | - recipe[apt] 48 | 49 | - name: ubuntu-1004 50 | driver_plugin: digitalocean 51 | driver_config: 52 | image_id: 14097 53 | flavor_id: 63 54 | region_id: 4 55 | ssh_key_ids: <%= ENV['DIGITAL_OCEAN_SSH_KEY_IDS'] %> 56 | run_list: 57 | - recipe[apt] 58 | 59 | - name: ubuntu-1204 60 | driver_plugin: digitalocean 61 | driver_config: 62 | image_id: 1505447 63 | flavor_id: 63 64 | region_id: 4 65 | ssh_key_ids: <%= ENV['DIGITAL_OCEAN_SSH_KEY_IDS'] %> 66 | run_list: 67 | - recipe[apt] 68 | 69 | - name: ubuntu-1304 70 | driver_plugin: digitalocean 71 | driver_config: 72 | image_id: 350076 73 | flavor_id: 63 74 | region_id: 4 75 | ssh_key_ids: <%= ENV['DIGITAL_OCEAN_SSH_KEY_IDS'] %> 76 | run_list: 77 | - recipe[apt] 78 | 79 | - name: ubuntu-1310 80 | driver_plugin: digitalocean 81 | driver_config: 82 | image_id: 1505699 83 | flavor_id: 63 84 | region_id: 4 85 | ssh_key_ids: <%= ENV['DIGITAL_OCEAN_SSH_KEY_IDS'] %> 86 | run_list: 87 | - recipe[apt] 88 | 89 | suites: 90 | - name: default 91 | run_list: 92 | - recipe[minitest-handler] 93 | - recipe[rabbitmq::default] 94 | attributes: {} 95 | -------------------------------------------------------------------------------- /providers/policy.rb: -------------------------------------------------------------------------------- 1 | # 2 | # Cookbook Name:: rabbitmq 3 | # Provider:: policy 4 | # 5 | # Author: Robert Choi 6 | # Copyright 2013 by Robert Choi 7 | # 8 | # Licensed under the Apache License, Version 2.0 (the "License"); 9 | # you may not use this file except in compliance with the License. 10 | # You may obtain a copy of the License at 11 | # 12 | # http://www.apache.org/licenses/LICENSE-2.0 13 | # 14 | # Unless required by applicable law or agreed to in writing, software 15 | # distributed under the License is distributed on an "AS IS" BASIS, 16 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 17 | # See the License for the specific language governing permissions and 18 | # limitations under the License. 19 | # 20 | 21 | require 'shellwords' 22 | 23 | def policy_exists?(vhost, name) 24 | cmd = 'rabbitmqctl list_policies' 25 | cmd << " -p #{Shellwords.escape vhost}" unless vhost.nil? 26 | cmd << " |grep '#{name}\\b'" 27 | 28 | cmd = Mixlib::ShellOut.new(cmd) 29 | cmd.environment['HOME'] = ENV.fetch('HOME', '/root') 30 | cmd.run_command 31 | begin 32 | cmd.error! 33 | true 34 | rescue 35 | false 36 | end 37 | end 38 | 39 | action :set do 40 | unless policy_exists?(new_resource.vhost, new_resource.policy) 41 | cmd = 'rabbitmqctl set_policy' 42 | cmd << " -p #{new_resource.vhost}" unless new_resource.vhost.nil? 43 | cmd << " #{new_resource.policy}" 44 | cmd << " \"#{new_resource.pattern}\"" 45 | cmd << " '{" 46 | 47 | first_param = true 48 | new_resource.params.each do |key, value| 49 | cmd << ',' unless first_param 50 | 51 | if value.kind_of? String 52 | cmd << "\"#{key}\":\"#{value}\"" 53 | else 54 | cmd << "\"#{key}\":#{value}" 55 | end 56 | first_param = false 57 | end 58 | 59 | cmd << "}'" 60 | if node['rabbitmq']['version'] >= '3.2.0' 61 | cmd << " --priority #{new_resource.priority}" if new_resource.priority 62 | else 63 | cmd << " #{new_resource.priority}" if new_resource.priority 64 | end 65 | 66 | execute "set_policy #{new_resource.policy}" do 67 | command cmd 68 | end 69 | 70 | new_resource.updated_by_last_action(true) 71 | Chef::Log.info "Done setting RabbitMQ policy '#{new_resource.policy}'." 72 | end 73 | end 74 | 75 | action :clear do 76 | if policy_exists?(new_resource.vhost, new_resource.policy) 77 | execute "clear_policy #{new_resource.policy}" do 78 | command "rabbitmqctl clear_policy #{new_resource.policy}" 79 | end 80 | 81 | new_resource.updated_by_last_action(true) 82 | Chef::Log.info "Done clearing RabbitMQ policy '#{new_resource.policy}'." 83 | end 84 | end 85 | 86 | action :list do 87 | execute 'list_policies' do 88 | command 'rabbitmqctl list_policies' 89 | end 90 | 91 | new_resource.updated_by_last_action(true) 92 | end 93 | -------------------------------------------------------------------------------- /attributes/default.rb: -------------------------------------------------------------------------------- 1 | # Latest RabbitMQ.com version to install 2 | default['rabbitmq']['version'] = '3.1.5' 3 | # The distro versions may be more stable and have back-ported patches 4 | default['rabbitmq']['use_distro_version'] = false 5 | 6 | # being nil, the rabbitmq defaults will be used 7 | default['rabbitmq']['nodename'] = nil 8 | default['rabbitmq']['address'] = nil 9 | default['rabbitmq']['port'] = nil 10 | default['rabbitmq']['config'] = nil 11 | default['rabbitmq']['logdir'] = nil 12 | default['rabbitmq']['mnesiadir'] = '/var/lib/rabbitmq/mnesia' 13 | default['rabbitmq']['service_name'] = 'rabbitmq-server' 14 | 15 | # config file location 16 | # http://www.rabbitmq.com/configure.html#define-environment-variables 17 | # "The .config extension is automatically appended by the Erlang runtime." 18 | default['rabbitmq']['config_root'] = '/etc/rabbitmq' 19 | default['rabbitmq']['config'] = '/etc/rabbitmq/rabbitmq' 20 | default['rabbitmq']['erlang_cookie_path'] = '/var/lib/rabbitmq/.erlang.cookie' 21 | 22 | # rabbitmq.config defaults 23 | default['rabbitmq']['default_user'] = 'guest' 24 | default['rabbitmq']['default_pass'] = 'guest' 25 | 26 | # Erlang kernel application options 27 | # See http://www.erlang.org/doc/man/kernel_app.html 28 | default['rabbitmq']['kernel']['inet_dist_listen_min'] = nil 29 | default['rabbitmq']['kernel']['inet_dist_listen_max'] = nil 30 | 31 | # Tell Erlang what IP to bind to 32 | default['rabbitmq']['kernel']['inet_dist_use_interface'] = nil 33 | 34 | # clustering 35 | default['rabbitmq']['cluster'] = false 36 | default['rabbitmq']['cluster_disk_nodes'] = [] 37 | default['rabbitmq']['erlang_cookie'] = 'AnyAlphaNumericStringWillDo' 38 | default['rabbitmq']['cluster_partition_handling'] = 'ignore' 39 | 40 | # resource usage 41 | default['rabbitmq']['disk_free_limit_relative'] = nil 42 | default['rabbitmq']['vm_memory_high_watermark'] = nil 43 | default['rabbitmq']['max_file_descriptors'] = 1024 44 | default['rabbitmq']['open_file_limit'] = nil 45 | 46 | # job control 47 | default['rabbitmq']['job_control'] = 'initd' 48 | 49 | # ssl 50 | default['rabbitmq']['ssl'] = false 51 | default['rabbitmq']['ssl_port'] = 5671 52 | default['rabbitmq']['ssl_cacert'] = '/path/to/cacert.pem' 53 | default['rabbitmq']['ssl_cert'] = '/path/to/cert.pem' 54 | default['rabbitmq']['ssl_key'] = '/path/to/key.pem' 55 | default['rabbitmq']['ssl_verify'] = 'verify_none' 56 | default['rabbitmq']['ssl_fail_if_no_peer_cert'] = false 57 | default['rabbitmq']['web_console_ssl'] = false 58 | default['rabbitmq']['web_console_ssl_port'] = 15_671 59 | 60 | # tcp listen options 61 | default['rabbitmq']['tcp_listen_packet'] = 'raw' 62 | default['rabbitmq']['tcp_listen_reuseaddr'] = true 63 | default['rabbitmq']['tcp_listen_backlog'] = 128 64 | default['rabbitmq']['tcp_listen_nodelay'] = true 65 | default['rabbitmq']['tcp_listen_exit_on_close'] = false 66 | default['rabbitmq']['tcp_listen_keepalive'] = false 67 | 68 | # virtualhosts 69 | default['rabbitmq']['virtualhosts'] = [] 70 | default['rabbitmq']['disabled_virtualhosts'] = [] 71 | 72 | # users 73 | default['rabbitmq']['enabled_users'] = 74 | [{ :name => 'guest', :password => 'guest', :rights => 75 | [{ :vhost => nil , :conf => '.*', :write => '.*', :read => '.*' }] 76 | }] 77 | default['rabbitmq']['disabled_users'] = [] 78 | 79 | # plugins 80 | default['rabbitmq']['enabled_plugins'] = [] 81 | default['rabbitmq']['disabled_plugins'] = [] 82 | 83 | # platform specific settings 84 | case node['platform_family'] 85 | when 'smartos' 86 | default['rabbitmq']['service_name'] = 'rabbitmq' 87 | default['rabbitmq']['config_root'] = '/opt/local/etc/rabbitmq' 88 | default['rabbitmq']['config'] = '/opt/local/etc/rabbitmq/rabbitmq' 89 | default['rabbitmq']['erlang_cookie_path'] = '/var/db/rabbitmq/.erlang.cookie' 90 | end 91 | 92 | # Example HA policies 93 | default['rabbitmq']['policies']['ha-all']['pattern'] = '^(?!amq\\.).*' 94 | default['rabbitmq']['policies']['ha-all']['params'] = { 'ha-mode' => 'all' } 95 | default['rabbitmq']['policies']['ha-all']['priority'] = 0 96 | 97 | default['rabbitmq']['policies']['ha-two']['pattern'] = "^two\." 98 | default['rabbitmq']['policies']['ha-two']['params'] = { 'ha-mode' => 'exactly', 'ha-params' => 2 } 99 | default['rabbitmq']['policies']['ha-two']['priority'] = 1 100 | 101 | default['rabbitmq']['disabled_policies'] = [] 102 | -------------------------------------------------------------------------------- /metadata.rb: -------------------------------------------------------------------------------- 1 | name 'rabbitmq' 2 | maintainer 'Opscode, Inc.' 3 | maintainer_email 'cookbooks@opscode.com' 4 | license 'Apache 2.0' 5 | description 'Installs and configures RabbitMQ server' 6 | version '3.2.1' 7 | recipe 'rabbitmq', 'Install and configure RabbitMQ' 8 | recipe 'rabbitmq::cluster', 'Set up RabbitMQ clustering.' 9 | recipe 'rabbitmq::plugin_management', 'Manage plugins with node attributes' 10 | recipe 'rabbitmq::virtualhost_management', 'Manage virtualhost with node attributes' 11 | recipe 'rabbitmq::user_management', 'Manage users with node attributes' 12 | depends 'erlang', '>= 0.9' 13 | 14 | supports 'debian' 15 | supports 'ubuntu' 16 | supports 'redhat' 17 | supports 'centos' 18 | supports 'scientific' 19 | supports 'amazon' 20 | supports 'oracle' 21 | supports 'smartos' 22 | supports 'suse' 23 | 24 | attribute 'rabbitmq', 25 | :display_name => 'RabbitMQ', 26 | :description => 'Hash of RabbitMQ attributes', 27 | :type => 'hash' 28 | 29 | attribute 'rabbitmq/nodename', 30 | :display_name => 'RabbitMQ Erlang node name', 31 | :description => 'The Erlang node name for this server.', 32 | :default => "node['hostname']" 33 | 34 | attribute 'rabbitmq/address', 35 | :display_name => 'RabbitMQ server IP address', 36 | :description => 'IP address to bind.' 37 | 38 | attribute 'rabbitmq/port', 39 | :display_name => 'RabbitMQ server port', 40 | :description => 'TCP port to bind.' 41 | 42 | attribute 'rabbitmq/config', 43 | :display_name => 'RabbitMQ config file to load', 44 | :description => 'Path to the rabbitmq.config file, if any.' 45 | 46 | attribute 'rabbitmq/logdir', 47 | :display_name => 'RabbitMQ log directory', 48 | :description => 'Path to the directory for log files.' 49 | 50 | attribute 'rabbitmq/mnesiadir', 51 | :display_name => 'RabbitMQ Mnesia database directory', 52 | :description => 'Path to the directory for Mnesia database files.' 53 | 54 | attribute 'rabbitmq/cluster', 55 | :display_name => 'RabbitMQ clustering', 56 | :description => 'Whether to activate clustering.', 57 | :default => 'no' 58 | 59 | attribute 'rabbitmq/cluster_config', 60 | :display_name => 'RabbitMQ clustering configuration file', 61 | :description => 'Path to the clustering configuration file, if cluster is yes.', 62 | :default => '/etc/rabbitmq/rabbitmq_cluster.config' 63 | 64 | attribute 'rabbitmq/cluster_disk_nodes', 65 | :display_name => 'RabbitMQ cluster disk nodes', 66 | :description => 'Array of member Erlang nodenames for the disk-based storage nodes in the cluster.', 67 | :default => [], 68 | :type => 'array' 69 | 70 | attribute 'rabbitmq/erlang_cookie', 71 | :display_name => 'RabbitMQ Erlang cookie', 72 | :description => 'Access cookie for clustering nodes. There is no default.' 73 | 74 | attribute 'rabbitmq/virtualhosts', 75 | :display_name => 'Virtualhosts on rabbitmq instance', 76 | :description => 'List all virtualhosts that will exist', 77 | :default => [], 78 | :type => 'array' 79 | 80 | attribute 'rabbitmq/enabled_users', 81 | :display_name => 'Users and their rights on rabbitmq instance', 82 | :description => 'Users and description of their rights', 83 | :default => [{ :name => 'guest', :password => 'guest', :rights => [{ :vhost => nil , :conf => '.*', :write => '.*', :read => '.*' }] }], 84 | :type => 'array' 85 | 86 | attribute 'rabbitmq/disabled_users', 87 | :display_name => 'Disabled users', 88 | :description => 'List all users that will be deactivated', 89 | :default => [], 90 | :type => 'array' 91 | 92 | attribute 'rabbitmq/enabled_plugins', 93 | :display_name => 'Enabled plugins', 94 | :description => 'List all plugins that will be activated', 95 | :default => [], 96 | :type => 'array' 97 | 98 | attribute 'rabbitmq/disabled_plugins', 99 | :display_name => 'Disabled plugins', 100 | :description => 'List all plugins that will be deactivated', 101 | :default => [], 102 | :type => 'array' 103 | 104 | attribute 'rabbitmq/local_erl_networking', 105 | :display_name => 'Local Erlang networking', 106 | :description => 'Bind erlang networking to localhost' 107 | 108 | attribute 'rabbitmq/erl_networking_bind_address', 109 | :display_name => 'Erl Networking Bind Address', 110 | :description => 'Bind Rabbit and erlang networking to an address' 111 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | rabbitmq Cookbook CHANGELOG 2 | =========================== 3 | This file is used to list changes made in each version of the rabbitmq cookbook. 4 | 5 | 6 | v3.2.0 (2014-04-23) 7 | ------------------- 8 | - [COOK-4517] - Add cluster partition handling attribute to the cookbook 9 | 10 | 11 | v3.1.0 (2014-03-27) 12 | ------------------- 13 | - [COOK-4459] - added missing dependency package logrotate 14 | - [COOK-4279] - Addition of ssl_opts in rabbitmq.config when web_console_ssl is enabled 15 | 16 | 17 | v3.0.4 (2014-03-19) 18 | ------------------- 19 | - [COOK-4431] - RPM / DEB package installs now use the rabbit version you specify 20 | - [COOK-4438] - rabbitmq_policy resource breaks if you use rabbitmq version >= 3.2 21 | 22 | 23 | v3.0.2 (2014-02-27) 24 | ------------------- 25 | - [COOK-4384] Add ChefSpec Custom Matchers for LWRPs 26 | 27 | 28 | v3.0.0 (2014-02-27) 29 | ------------------- 30 | [COOK-4369] - use_inline_resources 31 | 32 | 33 | v2.4.2 (2014-02-27) 34 | ------------------- 35 | [COOK-4280] Upstart script properly waits until the server is started 36 | 37 | 38 | v2.4.0 (2014-02-14) 39 | ------------------- 40 | - [COOK-4050] - Do not force failure in rabbitmq_user 41 | - [COOK-4088] - Update rabbitmq.config for port ranges 42 | - Updating test harness. Fixing style cops 43 | 44 | 45 | v2.3.2 46 | ------ 47 | ### Bug 48 | - **[COOK-3678](https://tickets.opscode.com/browse/COOK-3678)** - Fix an issue where a RabbitMQ policy resource with vhost arguments emits unexpected restart notification 49 | - **[COOK-3606](https://tickets.opscode.com/browse/COOK-3606)** - Fix erlang cookie comparison 50 | - **[COOK-3512](https://tickets.opscode.com/browse/COOK-3512)** - Define rabbitmq service on SUSE 51 | 52 | ### New Feature 53 | - **[COOK-3538](https://tickets.opscode.com/browse/COOK-3538)** - Configure web management console to use SSL 54 | 55 | 56 | v2.3.0 57 | ------ 58 | ### Improvement 59 | - **[COOK-3369](https://tickets.opscode.com/browse/COOK-3369)** - Add SUSE support 60 | - **[COOK-3320](https://tickets.opscode.com/browse/COOK-3320)** - Configure bind and cluster over a specified addr 61 | - **[COOK-3138](https://tickets.opscode.com/browse/COOK-3138)** - Do not log RabbitMQ password 62 | - **[COOK-2803](https://tickets.opscode.com/browse/COOK-2803)** - Bind erlang networking to localhost (attribute-driven) 63 | 64 | v2.2.0 65 | ------ 66 | ### Improvement 67 | - Greatly expanded Test Kitchen coverage and platform support 68 | - added support for disabling policies and virtualhosts through attributes 69 | - added support for using with the erlang::esl recipe 70 | - [COOK-2705]: Add ability to change tcp_listen_options in config 71 | - [COOK-2397]: Added upstart support to rabbitmq cookbook 72 | - [COOK-2830]: Use a notify for server restart, instead of defining a new service 73 | - [COOK-3384]: Added ability to change user password 74 | - [COOK-3489]: Add attribute to set open file limit 75 | 76 | ### Bug 77 | - [COOK-3011]: Incorrect apt source test causes Chef run to fail on Ubuntu 78 | - [COOK-3438]: RabbitMQ fixes for Fedora 19 79 | 80 | v2.1.2 81 | ------ 82 | ### Improvement 83 | - [COOK-3099]: policy resource should support optional vhost argument 84 | 85 | ### Bug 86 | 87 | - [COOK-3078]: rabbitmq password is not quoted or escaped on add_user 88 | - [COOK-3079]: rabbitmq permissions check doesn't match, resulting in non-idempotency 89 | 90 | v2.1.0 91 | ------ 92 | ### Bug 93 | - [COOK-2828]: Rabbitmq Clustering doesn't work properly 94 | - [COOK-2975]: rabbitmq has foodcritic failures 95 | 96 | ### New Feature 97 | - [COOK-2575]: LWRP for setting policies 98 | 99 | v2.0.0 100 | ------ 101 | - Major v2.0 changes are documented in the README. 102 | - [COOK-2391] - Added support for verify verify_peer and fail_if_no_peer_cert true 103 | - [COOK-2153] - Fix of user LWRP 104 | - [COOK-2180] - Plugin management via node attributes 105 | - [COOK-2201] - Use the proper syntax when using rabbitmq 3.0 instead of 2.x 106 | - [COOK-2210] - User management via node attributes 107 | - [COOK-2211] - Virtualhost management via node attributes 108 | - [COOK-2235] - RabbitMQ bin path isn't necessarily part of PATH for the plugin provider 109 | - [COOK-2392] - correctly configure a rabbitmq cluster 110 | - [COOK-2366] - Default recipe doesn't create mnesia dir 111 | - [COOK-2416] - Add support for clearing tags. 112 | 113 | v1.8.0 114 | ------ 115 | - [COOK-2151] - Add config options for `disk_free_limit` and `vm_memory_high_watermark` via attributes 116 | 117 | v1.7.0 118 | ------ 119 | - [COOK-1850] - oracle linux support 120 | - [COOK-1873] - add `set_user_tag` action to `rabbitmq_user` LWRP 121 | - [COOK-1878] - :immediately action causes clustering to fail 122 | - [COOK-1888] - smartos support 123 | 124 | v1.6.4 125 | ------ 126 | - [COOK-1684] - Unify behavior of debian and rhel clones in the rabbitmq cookbook 127 | - [COOK-1724] - enable using the distro release of rabbitmq instead of the RabbitMQ.org version 128 | 129 | v1.6.2 130 | ------ 131 | - [COOK-1552] - removed rogue single quote from rabbitmq ssl configuration 132 | 133 | v1.6.0 134 | ------ 135 | - [COOK-1496] - explicitly include the apt recipe 136 | - [COOK-1501] - Allow user to enable yum-based installation of rabbitmq via an attribute 137 | - [COOK-1503] - Recipe to enable rabbitmq web management console 138 | 139 | v1.5.0 140 | ------ 141 | This version requires apt cookbook v1.4.4 (reflected in metadata). 142 | 143 | - [COOK-1216] - add amazon linux to RHELish platforms 144 | - [COOK-1217] - specify version, for RHELish platforms 145 | - [COOK-1219] - immediately restart service on config update 146 | - [COOK-1317] - fix installation of old version from ubuntu APT repo 147 | - [COOK-1331] - LWRP for enabling/disabling rabbitmq plugins 148 | - [COOK-1386] - increment rabbitmq version to 2.8.4 149 | - [COOK-1432] - resolve foodcritic warnings 150 | - [COOK-1438] - add fedora to RHELish platforms 151 | 152 | v1.4.1 153 | ------ 154 | - [COOK-1386] - Bumped version to 2.8.4 155 | - rabbitmq::default now includes erlang::default 156 | 157 | v1.4.0 158 | ------ 159 | - [COOK-911] - Auto clustering support 160 | 161 | v1.3.2 162 | ------ 163 | - [COOK-585] - manage rabbitmq-server service 164 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | rabbitmq Cookbook 2 | ================= 3 | 4 | **NOTE: The fixes that this fork was created for have been merged into the main opscode repo. I recommended that everyone uses that to keep as up to date as possible: https://github.com/opscode-cookbooks/rabbitmq** 5 | 6 | This is a cookbook for managing RabbitMQ with Chef. It is intended for 2.6.1 or later releases. 7 | 8 | **Version 2.0 Changes** 9 | 10 | The 2.0 release of the cookbook defaults to using the latest version available from RabbitMQ.com via direct download of the package. This was done to simplify the installation options to either distro package or direct download. The attributes `use_apt` and `use_yum` have been removed as have the `apt` and `yum` cookbook dependencies. The user LWRP action `:set_user_tags` was changed to `:set_tags` for consistency with other actions. 11 | 12 | 13 | Requirements 14 | ------------ 15 | This cookbook depends on the `erlang` cookbook. 16 | 17 | Please refer to the [TESTING file](TESTING.md) to see the currently (and passing) tested platforms. The release was tested with (rabbitmq.com/distro version): 18 | - CentOS 5.9: 3.1.5 (distro release unsupported) 19 | - CentOS 6.4: 3.1.5/2.6.1 (no lwrps support) 20 | - Fedora 18: 3.1.5 (distro release unsupported) 21 | - Ubuntu 10.04: 3.1.5 (distro release unsupported) 22 | - Ubuntu 12.04: 3.1.5/2.7.1 (no lwrps support) 23 | - Ubuntu 13.04: 3.1.5/3.0.2 24 | 25 | 26 | Recipes 27 | ------- 28 | ### default 29 | Installs `rabbitmq-server` from RabbitMQ.com via direct download of the installation package or using the distribution version. Depending on your distribution, the provided version may be quite old so they are disabled by default. If you want to use the distro version, set the attribute `['rabbitmq']['use_distro_version']` to `true`. You may override the download URL attribute `['rabbitmq']['package']` if you wish to use a local mirror. 30 | 31 | The cluster recipe is now combined with the default and will now auto-cluster. Set the `['rabbitmq']['cluster']` attribute to `true`, `['rabbitmq']['cluster_disk_nodes']` array of `node@host` strings that describe which you want to be disk nodes and then set an alphanumeric string for the `erlang_cookie`. 32 | 33 | To enable SSL turn `ssl` to `true` and set the paths to your cacert, cert and key files. 34 | 35 | ### mgmt_console 36 | Installs the `rabbitmq_management` and `rabbitmq_management_visualiser` plugins. 37 | To use https connection to management console, turn `['rabbitmq']['web_console_ssl']` to true. The SSL port for web management console can be configured by setting attribute `['rabbitmq']['web_console_ssl_port']`, whose default value is 15671. 38 | 39 | ### plugin_management 40 | Enables any plugins listed in the `node['rabbitmq']['enabled_plugins']` and disables any listed in `node['rabbitmq'][disabled_plugins']` attributes. 41 | 42 | ### policy_management 43 | Enables any policies listed in the `node['rabbitmq'][policies]` and disables any listed in `node['rabbitmq'][disabled_policies]` attributes. 44 | 45 | ### user_management 46 | Enables any users listed in the `node['rabbitmq']['enabled_users]` and disables any listed in `node['rabbitmq'][disabled_users]` attributes. 47 | 48 | ### virtualhost_management 49 | Enables any vhosts listed in the `node['rabbitmq'][virtualhosts]` and disables any listed in `node['rabbitmq'][disabled_virtualhosts]` attributes. 50 | 51 | 52 | Resources/Providers 53 | ------------------- 54 | There are 4 LWRPs for interacting with RabbitMQ. 55 | 56 | ### plugin 57 | Enables or disables a rabbitmq plugin. Plugins are not supported for releases prior to 2.7.0. 58 | 59 | - `:enable` enables a `plugin` 60 | - `:disable` disables a `plugin` 61 | 62 | #### Examples 63 | ```ruby 64 | rabbitmq_plugin "rabbitmq_stomp" do 65 | action :enable 66 | end 67 | ``` 68 | 69 | ```ruby 70 | rabbitmq_plugin "rabbitmq_shovel" do 71 | action :disable 72 | end 73 | ``` 74 | 75 | ### policy 76 | sets or clears a rabbitmq policy. 77 | 78 | - `:set` sets a `policy` 79 | - `:clear` clears a `policy` 80 | - `:list` lists `policy`s 81 | 82 | #### Examples 83 | ```ruby 84 | rabbitmq_policy "ha-all" do 85 | pattern "^(?!amq\\.).*" 86 | params {"ha-mode"=>"all"} 87 | priority 1 88 | action :set 89 | end 90 | ``` 91 | 92 | ```ruby 93 | rabbitmq_policy "ha-all" do 94 | action :clear 95 | end 96 | ``` 97 | 98 | ### user 99 | Adds and deletes users, fairly simplistic permissions management. 100 | 101 | - `:add` adds a `user` with a `password` 102 | - `:delete` deletes a `user` 103 | - `:set_permissions` sets the `permissions` for a `user`, `vhost` is optional 104 | - `:clear_permissions` clears the permissions for a `user` 105 | - `:set_tags` set the tags on a user 106 | - `:clear_tags` clear any tags on a user 107 | - `:change_password` set the `password` for a `user` 108 | 109 | #### Examples 110 | ```ruby 111 | rabbitmq_user "guest" do 112 | action :delete 113 | end 114 | ``` 115 | 116 | ```ruby 117 | rabbitmq_user "nova" do 118 | password "sekret" 119 | action :add 120 | end 121 | ``` 122 | 123 | ```ruby 124 | rabbitmq_user "nova" do 125 | vhost "/nova" 126 | permissions ".* .* .*" 127 | action :set_permissions 128 | end 129 | ``` 130 | 131 | ```ruby 132 | rabbitmq_user "joe" do 133 | tag "admin,lead" 134 | action :set_tags 135 | end 136 | ``` 137 | 138 | ### vhost 139 | Adds and deletes vhosts. 140 | 141 | - `:add` adds a `vhost` 142 | - `:delete` deletes a `vhost` 143 | 144 | #### Examples 145 | ``` ruby 146 | rabbitmq_vhost "/nova" do 147 | action :add 148 | end 149 | ``` 150 | 151 | 152 | Limitations 153 | ----------- 154 | For an already running cluster, these actions still require manual intervention: 155 | - changing the :erlang_cookie 156 | - turning :cluster from true to false 157 | 158 | 159 | License & Authors 160 | ----------------- 161 | - Author:: Benjamin Black 162 | - Author:: Daniel DeLeo 163 | - Author:: Matt Ray () 164 | 165 | ```text 166 | Copyright (c) 2009-2013, Opscode, Inc. 167 | 168 | Licensed under the Apache License, Version 2.0 (the "License"); 169 | you may not use this file except in compliance with the License. 170 | You may obtain a copy of the License at 171 | 172 | http://www.apache.org/licenses/LICENSE-2.0 173 | 174 | Unless required by applicable law or agreed to in writing, software 175 | distributed under the License is distributed on an "AS IS" BASIS, 176 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 177 | See the License for the specific language governing permissions and 178 | limitations under the License. 179 | ``` 180 | -------------------------------------------------------------------------------- /TESTING.md: -------------------------------------------------------------------------------- 1 | TESTING doc 2 | ======================== 3 | 4 | Bundler 5 | ------- 6 | A ruby environment with Bundler installed is a prerequisite for using 7 | the testing harness shipped with this cookbook. At the time of this 8 | writing, it works with Ruby 2.0 and Bundler 1.5.3. All programs 9 | involved, with the exception of Vagrant, can be installed by cd'ing 10 | into the parent directory of this cookbook and running "bundle install" 11 | 12 | Rakefile 13 | -------- 14 | The Rakefile ships with a number of tasks, each of which can be ran 15 | individually, or in groups. Typing "rake" by itself will perform style 16 | checks with Rubocop and Foodcritic, ChefSpec with rspec, and 17 | integration with Test Kitchen using the Vagrant driver by 18 | default.Alternatively, integration tests can be ran with Test Kitchen 19 | cloud drivers. 20 | 21 | ``` 22 | $ rake -T 23 | rake integration:cloud # Run Test Kitchen with cloud plugins 24 | rake integration:vagrant # Run Test Kitchen with Vagrant 25 | rake spec # Run ChefSpec examples 26 | rake style # Run all style checks 27 | rake style:chef # Lint Chef cookbooks 28 | rake style:ruby # Run Ruby style checks 29 | rake travis # Run all tests on Travis 30 | ``` 31 | 32 | Style Testing 33 | ------------- 34 | Ruby style tests can be performed by Rubocop by issuing either 35 | ``` 36 | bundle exec rubocop 37 | ``` 38 | or 39 | ``` 40 | rake style:ruby 41 | ``` 42 | 43 | Chef style tests can be performed with Foodcritic by issuing either 44 | ``` 45 | bundle exec foodcritic 46 | ``` 47 | or 48 | ``` 49 | rake style:chef 50 | ``` 51 | 52 | Spec Testing 53 | ------------- 54 | Unit testing is done by running Rspec examples. Rspec will test any 55 | libraries, then test recipes using ChefSpec. This works by compiling a 56 | recipe (but not converging it), and allowing the user to make 57 | assertions about the resource_collection. 58 | 59 | Integration Testing 60 | ------------------- 61 | Integration testing is performed by Test Kitchen. Test Kitchen will 62 | use either the Vagrant driver or various cloud drivers to instantiate 63 | machines and apply cookbooks. After a successful converge, tests are 64 | uploaded and ran out of band of Chef. Tests should be designed to 65 | ensure that a recipe has accomplished its goal. 66 | 67 | Integration Testing using Vagrant 68 | --------------------------------- 69 | Integration tests can be performed on a local workstation using 70 | Virtualbox or VMWare. Detailed instructions for setting this up can be 71 | found at the [Bento](https://github.com/opscode/bento) project web site. 72 | 73 | Integration tests using Vagrant can be performed with either 74 | ``` 75 | bundle exec kitchen test 76 | ``` 77 | or 78 | ``` 79 | rake integration:vagrant 80 | ``` 81 | 82 | Integration Testing using Cloud providers 83 | ----------------------------------------- 84 | Integration tests can be performed on cloud providers using 85 | Test Kitchen plugins. This cookbook ships a ```.kitchen.cloud.yml``` 86 | that references environmental variables present in the shell that 87 | ```kitchen test``` is ran from. These usually contain authentication 88 | tokens for driving IaaS APIs, as well as the paths to ssh private keys 89 | needed for Test Kitchen log into them after they've been created. 90 | 91 | Examples of environment variables being set in ```~/.bash_profile```: 92 | ``` 93 | # digital_ocean 94 | export DIGITAL_OCEAN_CLIENT_ID='your_bits_here' 95 | export DIGITAL_OCEAN_API_KEY='your_bits_here' 96 | export DIGITAL_OCEAN_SSH_KEY_IDS='your_bits_here' 97 | 98 | # aws 99 | export AWS_ACCESS_KEY_ID='your_bits_here' 100 | export AWS_SECRET_ACCESS_KEY='your_bits_here' 101 | export AWS_KEYPAIR_NAME='your_bits_here' 102 | 103 | # joyent 104 | export SDC_CLI_ACCOUNT='your_bits_here' 105 | export SDC_CLI_IDENTITY='your_bits_here' 106 | export SDC_CLI_KEY_ID='your_bits_here' 107 | ``` 108 | 109 | Integration tests using cloud drivers can be performed with either 110 | ``` 111 | export KITCHEN_YAML=.kitchen.cloud.yml 112 | bundle exec kitchen test 113 | ``` 114 | or 115 | ``` 116 | rake integration:cloud 117 | ``` 118 | 119 | Digital Ocean Hint 120 | ------------------ 121 | At the time of this writing, you cannot find the numerical values 122 | needed for your SSH_KEY_IDS from the GUI. Instead, you will need to 123 | access the API from the command line. 124 | 125 | curl -L 'https://api.digitalocean.com/ssh_keys/?client_id=your_bits_here&api_key=your_bits_here' 126 | 127 | Words about .travis.yml 128 | ----------------------- 129 | In order for Travis to perform integration tests on public cloud 130 | providers, two major things need to happen. First, the environment 131 | variables referenced by ```.kitchen.cloud.yml``` need to be made 132 | available. Second, the private half of the ssh keys needed to log into 133 | machines need to be dropped off on the machine. 134 | 135 | The first part is straight forward. The travis gem can encrypt 136 | environment variables against the public key on the Travis repository 137 | and add them to the .travis.yml. 138 | 139 | ``` 140 | gem install travis 141 | travis encrypt AWS_ACCESS_KEY_ID='your_bits_here' --add 142 | travis encrypt AWS_SECRET_ACCESS_'your_bits_here' --add 143 | travis encrypt AWS_KEYPAIR_NAME='your_bits_here' --add 144 | travis encrypt EC2_SSH_KEY_PATH='~/.ssh/id_ec2.pem' --add 145 | 146 | travis encrypt DIGITAL_OCEAN_CLIENT_ID='your_bits_here' --add 147 | travis encrypt DIGITAL_OCEAN_API_KEY='your_bits_here' --add 148 | travis encrypt DIGITAL_OCEAN_SSH_KEY_IDS='your_bits_here' --add 149 | travis encrypt DIGITAL_OCEAN_SSH_KEY_PATH='~/.ssh/id_do.pem' --add 150 | ``` 151 | 152 | The second part is a little more complicated. Travis ENV variables are 153 | restricted to 90 bytes, and will not fit an entire SSH key. This can 154 | be worked around by breaking them up into 90 byte chunks, stashing 155 | them into ENV variables, then digging them out in the 156 | ```before_install``` section of .travis.yml 157 | 158 | Here is an AWK script to do the encoding. 159 | ``` 160 | base64 ~/.ssh/travisci_cook_digitalocean.pem | \ 161 | awk '{ 162 | j=0; 163 | for( i=1; i> ~/.ssh/id_do.base64 183 | - cat ~/.ssh/id_do.base64 | tr -d ' ' | base64 --decode > ~/.ssh/id_do.pem 184 | - echo -n $EC2_KEY_CHUNK_{0..30} >> ~/.ssh/id_ec2.base64 185 | - cat ~/.ssh/id_ec2.base64 | tr -d ' ' | base64 --decode > ~/.ssh/id_ec2.pem 186 | ``` 187 | 188 | -------------------------------------------------------------------------------- /providers/user.rb: -------------------------------------------------------------------------------- 1 | # 2 | # Cookbook Name:: rabbitmq 3 | # Provider:: user 4 | # 5 | # Copyright 2011-2013, Opscode, Inc. 6 | # 7 | # Licensed under the Apache License, Version 2.0 (the "License"); 8 | # you may not use this file except in compliance with the License. 9 | # You may obtain a copy of the License at 10 | # 11 | # http://www.apache.org/licenses/LICENSE-2.0 12 | # 13 | # Unless required by applicable law or agreed to in writing, software 14 | # distributed under the License is distributed on an "AS IS" BASIS, 15 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | # See the License for the specific language governing permissions and 17 | # limitations under the License. 18 | # 19 | 20 | use_inline_resources 21 | 22 | def user_exists?(name) 23 | cmd = "rabbitmqctl -q list_users |grep '^#{name}\\b'" 24 | cmd = Mixlib::ShellOut.new(cmd) 25 | cmd.environment['HOME'] = ENV.fetch('HOME', '/root') 26 | cmd.run_command 27 | Chef::Log.debug "rabbitmq_user_exists?: #{cmd}" 28 | Chef::Log.debug "rabbitmq_user_exists?: #{cmd.stdout}" 29 | begin 30 | cmd.error! 31 | true 32 | rescue 33 | false 34 | end 35 | end 36 | 37 | def user_has_tag?(name, tag) 38 | tag = '"\[\]"' if tag.nil? 39 | cmd = "rabbitmqctl -q list_users | grep \"^#{name}\\b\" | grep #{tag}" 40 | cmd = Mixlib::ShellOut.new(cmd) 41 | cmd.environment['HOME'] = ENV.fetch('HOME', '/root') 42 | cmd.run_command 43 | Chef::Log.debug "rabbitmq_user_has_tag?: #{cmd}" 44 | Chef::Log.debug "rabbitmq_user_has_tag?: #{cmd.stdout}" 45 | begin 46 | cmd.error! 47 | true 48 | rescue RuntimeError 49 | false 50 | end 51 | end 52 | 53 | # does the user have the rights listed on the vhost? 54 | # empty perm_list means we're checking for any permissions 55 | def user_has_permissions?(name, vhost, perm_list = nil) 56 | vhost = '/' if vhost.nil? 57 | cmd = "rabbitmqctl -q list_user_permissions #{name} | grep \"^#{vhost}\\b\"" 58 | cmd = Mixlib::ShellOut.new(cmd) 59 | cmd.environment['HOME'] = ENV.fetch('HOME', '/root') 60 | cmd.run_command 61 | Chef::Log.debug "rabbitmq_user_has_permissions?: #{cmd}" 62 | Chef::Log.debug "rabbitmq_user_has_permissions?: #{cmd.stdout}" 63 | Chef::Log.debug "rabbitmq_user_has_permissions?: #{cmd.exitstatus}" 64 | if perm_list.nil? && cmd.stdout.empty? # looking for empty and found nothing 65 | Chef::Log.debug 'rabbitmq_user_has_permissions?: no permissions found' 66 | return false 67 | end 68 | if perm_list == cmd.stdout.split.drop(1) # existing match search 69 | Chef::Log.debug 'rabbitmq_user_has_permissions?: matching permissions already found' 70 | return true 71 | end 72 | Chef::Log.debug 'rabbitmq_user_has_permissions?: permissions found but do not match' 73 | false 74 | end 75 | 76 | action :add do 77 | unless user_exists?(new_resource.user) 78 | Chef::Application.fatal!('rabbitmq_user with action :add requires a non-nil/empty password.') if new_resource.password.nil? || new_resource.password.empty? 79 | 80 | # To escape single quotes in a shell, you have to close the surrounding single quotes, add 81 | # in an escaped single quote, and then re-open the original single quotes. 82 | # Since this string is interpolated once by ruby, and then a second time by the shell, we need 83 | # to escape the escape character ('\') twice. This is why the following is such a mess 84 | # of leaning toothpicks: 85 | new_password = new_resource.password.gsub("'", "'\\\\''") 86 | cmd = "rabbitmqctl add_user #{new_resource.user} '#{new_password}'" 87 | execute "rabbitmqctl add_user #{new_resource.user}" do 88 | command cmd 89 | Chef::Log.info "Adding RabbitMQ user '#{new_resource.user}'." 90 | end 91 | end 92 | end 93 | 94 | action :delete do 95 | if user_exists?(new_resource.user) 96 | cmd = "rabbitmqctl delete_user #{new_resource.user}" 97 | execute cmd do 98 | Chef::Log.debug "rabbitmq_user_delete: #{cmd}" 99 | Chef::Log.info "Deleting RabbitMQ user '#{new_resource.user}'." 100 | end 101 | end 102 | end 103 | 104 | action :set_permissions do 105 | Chef::Application.fatal!("rabbitmq_user action :set_permissions fails with non-existant '#{new_resource.user}' user.") unless user_exists?(new_resource.user) 106 | 107 | perm_list = new_resource.permissions.split 108 | unless user_has_permissions?(new_resource.user, new_resource.vhost, perm_list) 109 | vhostopt = "-p #{new_resource.vhost}" unless new_resource.vhost.nil? 110 | cmd = "rabbitmqctl set_permissions #{vhostopt} #{new_resource.user} \"#{perm_list.join("\" \"")}\"" 111 | execute cmd do 112 | Chef::Log.debug "rabbitmq_user_set_permissions: #{cmd}" 113 | Chef::Log.info "Setting RabbitMQ user permissions for '#{new_resource.user}' on vhost #{new_resource.vhost}." 114 | end 115 | end 116 | end 117 | 118 | action :clear_permissions do 119 | Chef::Application.fatal!("rabbitmq_user action :clear_permissions fails with non-existant '#{new_resource.user}' user.") unless user_exists?(new_resource.user) 120 | 121 | if user_has_permissions?(new_resource.user, new_resource.vhost) 122 | vhostopt = "-p #{new_resource.vhost}" unless new_resource.vhost.nil? 123 | cmd = "rabbitmqctl clear_permissions #{vhostopt} #{new_resource.user}" 124 | execute cmd do 125 | Chef::Log.debug "rabbitmq_user_clear_permissions: #{cmd}" 126 | Chef::Log.info "Clearing RabbitMQ user permissions for '#{new_resource.user}' from vhost #{new_resource.vhost}." 127 | end 128 | end 129 | end 130 | 131 | action :set_tags do 132 | Chef::Application.fatal!("rabbitmq_user action :set_tags fails with non-existant '#{new_resource.user}' user.") unless user_exists?(new_resource.user) 133 | 134 | unless user_has_tag?(new_resource.user, new_resource.tag) 135 | cmd = "rabbitmqctl set_user_tags #{new_resource.user} #{new_resource.tag}" 136 | execute cmd do 137 | Chef::Log.debug "rabbitmq_user_set_tags: #{cmd}" 138 | Chef::Log.info "Setting RabbitMQ user '#{new_resource.user}' tags '#{new_resource.tag}'" 139 | end 140 | end 141 | end 142 | 143 | action :clear_tags do 144 | Chef::Application.fatal!("rabbitmq_user action :clear_tags fails with non-existant '#{new_resource.user}' user.") unless user_exists?(new_resource.user) 145 | 146 | unless user_has_tag?(new_resource.user, '"\[\]"') 147 | cmd = "rabbitmqctl set_user_tags #{new_resource.user}" 148 | execute cmd do 149 | Chef::Log.debug "rabbitmq_user_clear_tags: #{cmd}" 150 | Chef::Log.info "Clearing RabbitMQ user '#{new_resource.user}' tags." 151 | end 152 | end 153 | end 154 | 155 | action :change_password do 156 | if user_exists?(new_resource.user) 157 | cmd = "rabbitmqctl change_password #{new_resource.user} #{new_resource.password}" 158 | execute cmd do 159 | Chef::Log.debug "rabbitmq_user_change_password: #{cmd}" 160 | Chef::Log.info "Editing RabbitMQ user '#{new_resource.user}'." 161 | end 162 | end 163 | end 164 | -------------------------------------------------------------------------------- /recipes/default.rb: -------------------------------------------------------------------------------- 1 | # 2 | # Cookbook Name:: rabbitmq 3 | # Recipe:: default 4 | # 5 | # Copyright 2009, Benjamin Black 6 | # Copyright 2009-2013, Opscode, Inc. 7 | # Copyright 2012, Kevin Nuckolls 8 | # 9 | # Licensed under the Apache License, Version 2.0 (the "License"); 10 | # you may not use this file except in compliance with the License. 11 | # You may obtain a copy of the License at 12 | # 13 | # http://www.apache.org/licenses/LICENSE-2.0 14 | # 15 | # Unless required by applicable law or agreed to in writing, software 16 | # distributed under the License is distributed on an "AS IS" BASIS, 17 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 18 | # See the License for the specific language governing permissions and 19 | # limitations under the License. 20 | # 21 | 22 | # 23 | class Chef::Resource 24 | include Opscode::RabbitMQ 25 | end 26 | 27 | include_recipe 'erlang' 28 | 29 | ## Install the package 30 | case node['platform_family'] 31 | when 'debian' 32 | # installs the required setsid command -- should be there by default but just in case 33 | package 'util-linux' 34 | # logrotate is a package dependency of rabbitmq-server 35 | package 'logrotate' 36 | 37 | if node['rabbitmq']['use_distro_version'] 38 | package 'rabbitmq-server' 39 | else 40 | # we need to download the package 41 | deb_package = "https://www.rabbitmq.com/releases/rabbitmq-server/v#{node['rabbitmq']['version']}/rabbitmq-server_#{node['rabbitmq']['version']}-1_all.deb" 42 | remote_file "#{Chef::Config[:file_cache_path]}/rabbitmq-server_#{node['rabbitmq']['version']}-1_all.deb" do 43 | source deb_package 44 | action :create_if_missing 45 | end 46 | dpkg_package "#{Chef::Config[:file_cache_path]}/rabbitmq-server_#{node['rabbitmq']['version']}-1_all.deb" 47 | end 48 | 49 | # Configure job control 50 | if node['rabbitmq']['job_control'] == 'upstart' 51 | # We start with stock init.d, remove it if we're not using init.d, otherwise leave it alone 52 | service node['rabbitmq']['service_name'] do 53 | action [:stop] 54 | only_if { File.exists?('/etc/init.d/rabbitmq-server') } 55 | end 56 | 57 | execute 'remove rabbitmq init.d command' do 58 | command 'update-rc.d -f rabbitmq-server remove' 59 | end 60 | 61 | file '/etc/init.d/rabbitmq-server' do 62 | action :delete 63 | end 64 | 65 | template "/etc/init/#{node['rabbitmq']['service_name']}.conf" do 66 | source 'rabbitmq.upstart.conf.erb' 67 | owner 'root' 68 | group 'root' 69 | mode 0644 70 | variables(:max_file_descriptors => node['rabbitmq']['max_file_descriptors']) 71 | end 72 | 73 | service node['rabbitmq']['service_name'] do 74 | provider Chef::Provider::Service::Upstart 75 | action [:enable, :start] 76 | # restart_command "stop #{node['rabbitmq']['service_name']} && start #{node['rabbitmq']['service_name']}" 77 | end 78 | end 79 | 80 | ## You'll see setsid used in all the init statements in this cookbook. This 81 | ## is because there is a problem with the stock init script in the RabbitMQ 82 | ## debian package (at least in 2.8.2) that makes it not daemonize properly 83 | ## when called from chef. The setsid command forces the subprocess into a state 84 | ## where it can daemonize properly. -Kevin (thanks to Daniel DeLeo for the help) 85 | if node['rabbitmq']['job_control'] == 'initd' 86 | service node['rabbitmq']['service_name'] do 87 | start_command 'setsid /etc/init.d/rabbitmq-server start' 88 | stop_command 'setsid /etc/init.d/rabbitmq-server stop' 89 | restart_command 'setsid /etc/init.d/rabbitmq-server restart' 90 | status_command 'setsid /etc/init.d/rabbitmq-server status' 91 | supports :status => true, :restart => true 92 | action [:enable, :start] 93 | end 94 | end 95 | 96 | when 'rhel', 'fedora' 97 | # This is needed since Erlang Solutions' packages provide "esl-erlang"; this package just requires "esl-erlang" and provides "erlang". 98 | if node['erlang']['install_method'] == 'esl' 99 | remote_file "#{Chef::Config[:file_cache_path]}/esl-erlang-compat.rpm" do 100 | source 'https://github.com/jasonmcintosh/esl-erlang-compat/blob/master/rpmbuild/RPMS/noarch/esl-erlang-compat-R14B-1.el6.noarch.rpm?raw=true' 101 | end 102 | rpm_package "#{Chef::Config[:file_cache_path]}/esl-erlang-compat.rpm" 103 | end 104 | 105 | if node['rabbitmq']['use_distro_version'] 106 | package 'rabbitmq-server' 107 | else 108 | # We need to download the rpm 109 | rpm_package = "https://www.rabbitmq.com/releases/rabbitmq-server/v#{node['rabbitmq']['version']}/rabbitmq-server-#{node['rabbitmq']['version']}-1.noarch.rpm" 110 | 111 | remote_file "#{Chef::Config[:file_cache_path]}/rabbitmq-server-#{node['rabbitmq']['version']}-1.noarch.rpm" do 112 | source rpm_package 113 | action :create_if_missing 114 | end 115 | rpm_package "#{Chef::Config[:file_cache_path]}/rabbitmq-server-#{node['rabbitmq']['version']}-1.noarch.rpm" 116 | end 117 | 118 | service node['rabbitmq']['service_name'] do 119 | action [:enable, :start] 120 | end 121 | 122 | when 'suse' 123 | # rabbitmq-server-plugins needs to be first so they both get installed 124 | # from the right repository. Otherwise, zypper will stop and ask for a 125 | # vendor change. 126 | package 'rabbitmq-server-plugins' 127 | package 'rabbitmq-server' 128 | 129 | service node['rabbitmq']['service_name'] do 130 | action [:enable, :start] 131 | end 132 | when 'smartos' 133 | package 'rabbitmq' 134 | 135 | service 'epmd' do 136 | action :start 137 | end 138 | 139 | service node['rabbitmq']['service_name'] do 140 | action [:enable, :start] 141 | end 142 | end 143 | 144 | if node['rabbitmq']['logdir'] 145 | directory node['rabbitmq']['logdir'] do 146 | owner 'rabbitmq' 147 | group 'rabbitmq' 148 | mode '775' 149 | recursive true 150 | end 151 | end 152 | 153 | directory node['rabbitmq']['mnesiadir'] do 154 | owner 'rabbitmq' 155 | group 'rabbitmq' 156 | mode '775' 157 | recursive true 158 | end 159 | 160 | template "#{node['rabbitmq']['config_root']}/rabbitmq-env.conf" do 161 | source 'rabbitmq-env.conf.erb' 162 | owner 'root' 163 | group 'root' 164 | mode 00644 165 | notifies :restart, "service[#{node['rabbitmq']['service_name']}]" 166 | end 167 | 168 | template "#{node['rabbitmq']['config_root']}/rabbitmq.config" do 169 | source 'rabbitmq.config.erb' 170 | owner 'root' 171 | group 'root' 172 | mode 00644 173 | variables( 174 | :kernel => format_kernel_parameters 175 | ) 176 | notifies :restart, "service[#{node['rabbitmq']['service_name']}]" 177 | end 178 | 179 | if File.exists?(node['rabbitmq']['erlang_cookie_path']) 180 | existing_erlang_key = File.read(node['rabbitmq']['erlang_cookie_path']).strip 181 | else 182 | existing_erlang_key = '' 183 | end 184 | 185 | if node['rabbitmq']['cluster'] && (node['rabbitmq']['erlang_cookie'] != existing_erlang_key) 186 | service "stop #{node['rabbitmq']['service_name']}" do 187 | service_name node['rabbitmq']['service_name'] 188 | pattern node['rabbitmq']['service_name'] 189 | action :stop 190 | end 191 | 192 | template node['rabbitmq']['erlang_cookie_path'] do 193 | source 'doterlang.cookie.erb' 194 | owner 'rabbitmq' 195 | group 'rabbitmq' 196 | mode 00400 197 | notifies :stop, "service[#{node['rabbitmq']['service_name']}]", :immediately 198 | notifies :start, "service[#{node['rabbitmq']['service_name']}]", :immediately 199 | notifies :run, 'execute[reset-node]', :immediately 200 | end 201 | 202 | # Need to reset for clustering # 203 | execute 'reset-node' do 204 | command 'rabbitmqctl stop_app && rabbitmqctl reset && rabbitmqctl start_app' 205 | action :nothing 206 | end 207 | end 208 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: ruby 2 | bundler_args: --without kitchen_vagrant 3 | rvm: 4 | - 2.1.0 5 | before_install: 6 | - echo -n $DO_KEY_CHUNK_{0..30} >> ~/.ssh/id_do.base64 7 | - cat ~/.ssh/id_do.base64 | tr -d ' ' | base64 --decode > ~/.ssh/id_do.pem 8 | - echo -n $EC2_KEY_CHUNK_{0..30} >> ~/.ssh/id_ec2.base64 9 | - cat ~/.ssh/id_ec2.base64 | tr -d ' ' | base64 --decode > ~/.ssh/id_ec2.pem 10 | script: 11 | - bundle exec rake travis 12 | after_script: 13 | - bundle exec kitchen destroy 14 | env: 15 | global: 16 | - secure: azjR7jwSlkSSx61D9WYoil0BB/ztHnud17F9nDfmqHIacgjO8szyQfF18eKal8/iPCFii4RrsTytHE1iEckbTqCssfg1QeFPjYZpllY0tKTjF5L3+DGn+pLrouhfwJpxo1Lo4s5wD0z4uFiAcGVJtw8I/Xh+xaGdOjYaVlLW/bI= 17 | - secure: NPKRM7REdLlEJ5dMOPcqNxBHprBfODRY70J/lu6uVWeGuEpriX0JVjzC4temMMjvY4UAzQMp4INOaqV/r0XVlYQecE2WW/o9vyBLcF6CscGsE69sRJPMOyIMmBxyLDSpVRvEqQ/InB2hmrf0jF8lfm9EcASPuPD7yvfQb0x85NQ= 18 | - secure: eWgiU283LbvB4eq0w287yxNjQVaemKWOgYrFkO5hEcNC64b2kPPw6yeqFgm0E5tt2R3b+VHF8C1CjLG4ww/C4u5lBqzi+oJodsGTN1IW0hWZrL/a62lWBgkHO1gd0eJO4apUJ9sb6MPaLrIfzc1WxClez6KXmC/MDeNGb12YJGU= 19 | - secure: Z20rOUTQ+IXErCPPV9chV//TksNV/I0qTfK36yNQtR2pg+U7NPuocnakF+4EvpzLjFBVW+QBnI6gwoFRZzXZYkkjOYRFl9B1zt3aHkWyilzo5GosP068Eqm9c7Tnwts7VSym962DBDn6u/rmQt5f0bOiy7T2jhSipnLIg58g780= 20 | - secure: g9Xb822U72BgEWPEDbqeNZRueN+JSrw4nz/C/Nwy4MgFDrrSyO4YjzkH+I50RXc+AUkpcAqFdU7Z6qDi+CVZas2C9ag4eq5bCwK0RGHRfwGbiYVePfUBjiYWG7ysH3MgJ9nCZnYK4EQSP1xstoU6aIcUUAT1GOztx9f3PBuj+As= 21 | - secure: H2jj7HHuNlWndMyOk4OY0d8s6OxiuL+wLVXZj0WEkFvwPyueYT32e78KVSBbjXG+mhogtOXz1Q9QXrURTlzKyCJGa6lvCAuPBFGCGCMZnlOhvZlEs+STui1qEQ5uGl9Bksow0xSmXczWLisEEU+BcsM1fOlQZ2mUm2B8OuugWD0= 22 | - secure: kwUXGf0OQxiwT6ffAT64+Umhn0Yf1ijX2i3l1w5/bJ/wn1KW6z/O3admu1G3g7oMA1OO5Z+l4qgvckdaRoDqdqp30iIyPdDWxsyYVGZcgHaDM9kDmmkDqeYFochFFZhhVBVog3zz+P28s6l89Rur0QPrCiZisOh38A8qwyj/aa0= 23 | - secure: BN35OVUDkNTFyhKD6gKhbPsMmIP+ffmqJHeceTnKCGX6rKr0OCXYXRzXGWm72pfUQ/zSGNZrhC+xfpcMxj5TM3ySOyIsC8jzu0ozZ6BOvJekHtj7laMOSnRZPe7ONcE/j3XSo8/OY9jlP/Buojv6btVcMZOjQWaMMu0/g1gxPsE= 24 | - secure: ZBCCT6EVRa/IQ7VuG4TtI+KHqeGQNJ/W95U+ll6iLO/VdGEtOi8qUgrYIglypmnihZNNDFdQU/yeFCLAzqbLtzOiBXZR0THbPPjWv9oIBRhcdYddz8p6I7MFQINDhAwSqE8BHvcPXS/XndATaD2A4qzHHILp1MP9S0RKAGVZsw8= 25 | - secure: hmdOgupqDuW9Rvv3LR7r53unaVrY/CbLaiHHiEVXNzCLeBsCbs3okhg60iNYVzvxMJ98gBe1FJA2JMPUwdZWkP1IzfQgxT0uV1GPlXi6ug76rBQ+QS7EmlbgSTgZMxecMjmcLNrm3BFeEWbwta0X1DNAQ3s2r+xyfUyKaaRTYag= 26 | - secure: YTS3w+4i5Zy+t+EKKEZC6k2H5E921zSFhq2EXIP5KRnrz2sUkkknBJIpQAo4KmvoJBWzmkwlIeIvb68MBaS+Nu0Pg9cNx7C699ZF5khcjnLeVg0vp/hUbHJsqJkJrnGLJc0ictZ2kbc+UMScNfm4Vu+0cf4VHrQjBE6tqZUqb2o= 27 | - secure: MJHjwrJAXf1h9eEkMWMkuIBEpr1jiT+GYwT6HcYzpsXvpBNWVK9RPzdmO4rDyDQsyqCeS23mir5/foNd5nYnYiidckThtCrkjDng632Rt0u6IDi1bLLnPYmX9Vl/Qb9vhNMnOsPzhh7DTNQsjVO0dkfCaosG9UOz9xkYlPDbBbo= 28 | - secure: WfIz/WvIEbI1k4PSqsnDwvPk5vxcf96UvZa86ec9+h6jbPc8pO5/cQqMyAxEkzkQ0KLd2Hi9ci525vicuoeBQyE9cMQ365z5Z26u/PBwbK3BtPWjc/k8LeEoKmOGOpNT0rpiXcEs00bWtjJpqxl/tvI3rlZ1mFcH0aOQjJ5uq7Y= 29 | - secure: eyw7iAVb+1Ug6hlIx1u2I+5DLo5VcPxZAxzVNOQcj1jaAmBsG0TlHQKhMQQV/5DMghp90nvJYM91UIcPn4xaAFzr9NoOAyFRtvJOJOm6Fv553pgSwmOko1namyPe1ewyXn6zX/gRrPOxCuRYWT0nm8HlW0xFJIGn/dDVZDWFPCo= 30 | - secure: iQPuZ7hRJ4bYm+PGTLsOF7x/VHjHGijNc3zsMrhkdRnoPai8s7oCoJU95p8xvsyYs1WjVjyPlKNsStw/0856v+iXmkrmTEKnjYsQaZpP0IZcKChEaRECaDxF2mvOOzMJ8vrIuxZ+5cXHzYljA7Bb88iBfg8kVYMsZjcNW/hFIZw= 31 | - secure: O5S9shUoBkQYiB6tcWGMCJmhz6S6CyZS6+LFXc33Mb+cqWiJOdu3LA88tGhhcA3m5guYUiNg3A3VrLIf/fmYu2vwJR5dPYu5TEOZQaC/fu5Jreff2StP9srTff/a82tb8n6Do/X3EUkSnLBOazJhS953nTbDqETSIcA+6Rq5rhg= 32 | - secure: CoCGwqt0ZByQB5CqieGA2MMgMMD76R6VxZTI35vhEbelVOO0yMtkEmdQgKs8qa+82Tss8caB4buEoqwEhmagPXfQClWY45iOfJSPBUhwgqQZtcl8NF+cYvOgmZVGaECsWCklOyXN9a329tOvdBCqnEnKISStFRloM5j1JH65MCY= 33 | - secure: JDdPbBZBiOxjPLQpo8cyWXWvLVB3c9ihhPphBjAUNFvW2LVyq2DWPlzosb0hM+yWMCK2k73ssqk8yxVjtoGNDymGGj11nJ/VAcSeaUp59G5dPYA+uqbnYd8ZqfkHthVBX5HurK3hk1Wjfgft1vkhuhWnPY6qtHwWVBMJ5HveVF0= 34 | - secure: bD1KvJ+b/q8aMd87GnkgwIkG1U69EEFGqsWH5bNZtNnTs6NHy2Ux+9ePR6E7ZWuFESKi/F/eWUowiGCafLfWiAabXxr3tbktgRj0vT9pu2Qsr9nLD3Q4wJkM/oB9kHKpAc7emnDLzYf5iDms05zuZyzMxdGeH61aG9DIk+0oX3g= 35 | - secure: PPftRhlRPDINFyggEccjW3N/muSzokc8Lw4bVcci0fZKCd//lBRXTwmf43MMsgX8bjLWSfzGSPw9AWtLgQ3B8hvS43yNaCIr130eKWy1qDJ4loTUE6R/TKEHqPzWT0SWlTDHZr9wmKYHbjRI1nsnLy0c5Hwz4MQo7Uz02ZfaN4c= 36 | - secure: Lk1NRLg0wnjSceQrHMnl4VOej0hVatwDCf2EmNqv2EZpLsaxsWnvvziHXLe/2a91gxMfe+6EuMpxxr3+RC4n+NGFI1ZXPu78myeCFqDVRX8f8jC0gSN5Yj+/KfxlOhAFX0j46Pb9IS3jMqmqmkIby8ae3LR19Aj1Zoe9sEb3xsU= 37 | - secure: XCHUDTNmHacW8dC92x1Z1n19J6ynqj9rfGyy74lxpGQXsyw6nY3Cdln/jxT1ZlRE1pPqNc8EIdv/AwAjWuTxfbciRDdji/ygFypTsiqCVrm5R6TWCY845vIc5bFATA3pAzyxyrIdLY1gyAK562qCKhuTFRv8TtaY7VNe3Co570w= 38 | - secure: Zehr1xLpC4MSnZTqNn1n5vzf8VWEo6xY9bStZCZsNDtHJmyg1/x6se11MCYCKQFEKBWLY+GD+D0NXBg1oMErrVTpcKMVECyzIe0n47dFZvTPbA5mRJ4x9MmTKYOmKfp2LUH+STtjWhQSmWLk48dSD05zUCWQEkImMRtxQhgjMz0= 39 | - secure: fAmrQhyHl0pHFuRKiMXlnbeQ0q2KCm6dO70latpMOFRrhea9QbOEXMwNRgEoCywRtXNVELSbqI+1sCFpDq/sKuKvROs6MHZYlvKbKRoA5+viWLOwVAwxkOYeHs89u7590nJwt9mh2pkMX4K50hpZG3xLt0A8FXTZ6ZL7U7ayRvk= 40 | - secure: SNBXfjdl0lHBNLEkCsrOYJ+EoyOrRdroywzV82rYsgoB78iH1DVQOnvl4aaxqRtWk+GCDmUI/7dEWmRCMvWJysax7xCdCRRFtjhsycjsDMmFZFaXZP6Y1qrInvQKjZuck86OwyWbMLRNJfKWDlKon4jCAtMm8CfAte5O3i5//R8= 41 | - secure: Q7RUohxTcGehfN8GmZwbA7xYiMSrTLZJqS/s80DwBJGZ80WbT7ueNIQgRxMuXJACIoIk/nzHZ7MywtTePltX0aiCBQ0NgWuzOBR1E8LBLjZxuXgqOee8Iiwf/j1hRBA7VVWJ/kdDGLlGe33AYWLJtyAG73CpZE2Uz4qjbP7hCzQ= 42 | - secure: CsY1FuFxWo/pfgqqr2dhROTfQqaxzvw2BZ2EajzbmA2kvphq7Ce89NQzbh0CGBMNQ3QwFMUqHpe2ugKfMP1i1zcBqS2JmTbYdDgzGsdQQ2UtEgRiwrUaCBG7ODdlrg7NcvN1Q6L36xSaiA0Eng4+Pan9PzkTWYO1fjtUuoTUK3Y= 43 | - secure: bqI9aoyOEU7nfPbyzgRGdrCxZZre6wjb0Zb7K7f1LPcqy0+OqBPt23BRJXbI8lOt1UxyyJsxDnN9NirRH9vCrjWyrtAWEXv+JojXW/1ltbjxxUzSe0nQWVB0A1NZfOP1LIQ8bakbr1wkZXbwwwZxrY+qzsBlk5m+EGU12Sah4Ds= 44 | - secure: cIcBpS1uaYS/lwW6KTy0PDdcr2mKxQEJMVgGLL77sPNOdoTQgZaAP21Cb881fjxujUIUMexmqcrv6exW4F350Glx1n6HKqnR+KkWuzDp15fJO1OxjUpheIgnQoaiYJkrcua6Jjr9m8p+PaLpmB3f9S0e36q2X9G6jCN8xN13gPI= 45 | - secure: G0KsBT7JsOu4jR7G/FtpcJD63EjYTHfEDWudZ/ayAh1lvkdAiTVZMOOdy7zPQ02WbMILJ8SOlEkCGzmYXi8BCaw5krDEgtn5kEC7ZoTmbtH+YeNj5nCTVbbm1eoI9PHthDEdANyHNUWYv/CF9zK1Bj187c7LBKI6XLtfMiwpqmc= 46 | - secure: Zlay7xrcdZxo9GlfZy8TBDdOZObYOCC1tbTMOqsbzNB2AgmFhjqhh9PK+DfAte+bdqtSBrlgs+4+xjZOD1tYUyDz7nm1a6mDp9IusHQshUpmWxhREJigEOQIOg2oSX1gUE2SnAYpgumjr6KanRBgU3sk+fVSksdk2+iTk1HDGyk= 47 | - secure: DHjSaiBL5etTNI4KigR+6VBom/J6JqUwdgh1I/b6uRPcNui+0hWtGUDHKKJO0XDTTgt0JuWcN7mcBfwfjK8gHaN7gp65rOrCs9tS0SQ9yfKEqY2Suf3PMFo6lOtYETiMNnNm46+M2SAa4ypk6UH1T82ZZECEx9H8jtQnV8MjXuU= 48 | - secure: SvEbFwEWDK2syCfhNJzJnARhKO+FMYgurgUn36gjZP9AaDhHFCb/M4brvN9miINXAHmTxj9/TbzxBlZ626uQpD2/ukmF0Mrp8mZl7hjpSWWHm0VKCEIb7RwtxAp/oRtfCqtC2yfseagd7rLxAaG5idHsv1KwxgUZucZ1jj4PYqk= 49 | - secure: Di1IpnnqAt3t5P728IH6bGYxAmk6cVnBoHcR7aRN4rVabsbSTRZVFl+UJ9PHT99GsCpt+nGBD6dPN7KVbQCnyR94bvQ21GSNA3tI9DtqGPQJp5loIGWsykkmUoTqPWqn/ZnZd8JbF7XQ9bF8scf/UqrIWenfXdC6dKS6jJZhcWQ= 50 | - secure: cDim7w+00G5gmfmxZlFOX2N3jsJcsdOrFV+aIQZWdZC843NST43pVDZ3XZFtRX3DU2ijSdnl4sF/jEPh52PafBNdwXOuJzNp9TJzM8oiey62jWSLJn96cR5kqvmj/xoxdMOWlfJ3oLXhccAoLI8mCrWfkmE9Qp2gNQuC1SnstWw= 51 | - secure: K3I+G+MNHZLS+45ELKxoeRnV3goLMqxHxUV4e2O01zswqSYsoGbVVQNID4UM/eP37FWuXHv43YiJP9yLRqjS5a8wIFWTAIRwopCADL5YvtmajhZsi+NGZolBgDzrvgBYTbR/tqvLAZKW5zEKJo2bW0k0dLxnCbnkVEsXS0I5xro= 52 | - secure: WoQTyxRICccnUsETvwmABpQtox/1FkV1cFlyhxaBSEWPn4TWHNLPo1LBrPZZaw3bo9D2bdpRggLJDTdgTfqLRGcmqjIf+8Y6UEsQFjCFSIIjrJiKBLXaC2UEDGA6Eg6XkDV98CuFE5k2K/ilbUBpWbgduYnh3WFe9gFVcF0pJiI= 53 | - secure: MG07/+Sv6rBEr7LMUygsY1fCVLtf+y4amg1B8tm9juOj/Q+Q+QwjX5oAwbKi6CujPHsgRyhsJaCcpzm0y0E7wPXm5aW1qgB8tEE2Wg0G9A8NsRgo+IjgGqZjdFMhZkc+IprOeHCSgEEBv0/jB2f20eXefDhgNYrt26eKQiwSfLA= 54 | - secure: V6uXhice6j83FbLGsdf3Vf6X63UfydGuyHxIVUgk87+pcdF8dd+1EcZiwgAdXnHo0hadl//zTIrjgxxZ/6BvVYYbSISPgb0paadW9ubN+7EIwW24jZlYOge3bWxfUWAAoIQIWawCji7HXAIZ4Xm/M4m+MCbwLy1vQ6iWStQvtrM= 55 | - secure: G2hDHPSXFqNCZtN14nin/OFzLh22yq6IXo2lky7TnyErZ2ly8gCTqMhhVTwqv9o2EQMGPgCv+qMQgZ+heNFNaWTZiXhnS9PFxoL3cAapgl6gkZ2XpGw8TAxIRM+msNLSZspPdXpjvAiMbGeQu1wZsZIfl8nJm9IC8VSQuO9R4nc= 56 | - secure: IIPh25E4irwXobetP0vglqaUXRyCqmlR26SHnwIHeyKIJQ8yEADcKfaOtGlF2HxKMSFJYx6svhZCDtW8HYbRcN/A1NDU4zVNu4nGbznCxhOPW21bll0IExF4kFRYWaj4L2jOrXyMIdn7HRW7CF88Ia//i2tC0RdNvUuQnODNEOc= 57 | - secure: ZZXRwlx43Uc9igC1/sGVGUu+UrPuZP4bDOhEr7r8pZO8/ZABA9wC26XZC2n/YHbuJn2Xq+EaOavLcLQcFPisMVRjMa+C1/pqxCzzIi78ezZ9m5dHP+jRanNi4DuzxUox75VumMIiToV6lk/AMRwO8vO3O7IQNDY6JKD4TShfztY= 58 | - secure: NAKeDv5feQ5Wi8CFuJ5L2EpnHyfcaSjzKvj5rEvzrycjmKMvDmoo/AWwiZEZ4ZhHgIQuEMysWM4LJrDaykQTRuAxflTWIxPaBCRI4cpbP+VH+K5ZC8s2+VRCq3bkOE/1iKjTTicfmPbqY01o2QEscHdU/EJwe9i0gylXREXGYCE= 59 | - secure: ZrXI6vg00ezKAEMKFyamn9+K9/sdWbBklcFXtuZZPYT8+q7Emwu3RS9yla1UD8YyiKokQ9kwzzNx9kHkpiXafsWUUG83DfiK/6pa1V5Zk0qXkVZLZJ/UTcuQhKBjC21wG3GxGryTuohRdwJ9MQC3WG1qRYdJDNpjHeln4SSiYGo= 60 | - secure: Ahf/aHxgxCUDYn59wRp/UQcTttSIhIY0Pv9wUzghUMUv+jsTzVLgoENVqOYevUZh4FOYjGtc1gVubo90HUltkurIUviHcc7NSlJX6sLJPyowz12nk9DA+0M86l4SmL0c2Sobb+3SK6F7wLpd0pqta3yASogjhBK+69tinOT3398= 61 | - secure: fvCzW0GtKtl6gHn+8zJV5bh1HwdmtmgbXcRGwGLwvZBtF8khUrzEZ24sYZM+LkCMdC79U/PwLpFqXTQuvaYhQhtGjVieg5ZGDdhwDA64BZWk98l/7y8L9EOqz3MfTBTaA7223hpdUi7QzxuTEkqtviofJ3caK7RiucYhztX/Nts= 62 | - secure: dd8fOK6ZP+pWxPqMrywu+MuEbHqs7Nel9PIyQlCVsUxjOGs76eoPYWGpXgjpj3zvFeGZ1CYRAtCDf6U/CNiurukXTCrCvPIx6wfSe9MmW/Pf1cshBPCWCiEJd9spzVcNZy28Z+z9DXQQVdLHsduAdLmT7w5BqT+Ih3LsbwSt3Bw= 63 | - secure: TBJK+k13v7p+lrST5PM9s6/GNKApKK+RVXtN8PWa01T4drFAVbCUr8ceLrzbzMI+8qtpsCeC2m/u3B6Js4RjB5zlZKNOqXL162K5ZdECjAyIwmzXEqdiNWGMKQTPAwy3mxlSNWVl25yXangp9ht5yC4/Ha2Ow116n0AhtSconG8= 64 | - secure: bs/pViqzDb3RY8iYjSkiVAxqIlkx66465152VwZV52p9l2a37RVwFpbgvSTdkQ3PTiNtTiXBtcqYKMY3XtLT9fStiZ4hbQ3e0ZheikArSL2G6/hWBSb+8OyonQC07DcQGXwRxQACyZSWiagss/0sE9NgHl2Zg7/M1T7Pv6hm8iI= 65 | - secure: OUNEUx6pNOrNdm4B5z5fiAT9Yub64zkvM0nKSI0XK5rV7D1m05T64kk7mJyp3+Eern+sDsFzMOIMJcFGk12tUrPQ+s/fPoLLYIJEBVUVBcw7E8IN4e5YGkgllg0W69qKbL5NmsCLVxwSkDM3kNxp394kPicxedPYpBz4oRHcnRI= 66 | - secure: fjCx18gyAEqHHmtfcGXgcSH6V7j486Zr4AHodnEaDGV9fOFW8YLuLOWp1IYanDwbpbVJxunQK+M1BG0uWYle7xlG39hv80tLQyA3cwPK77KmRdbycSklwXG5PIMjAJLGDpJk4k9jgx13R2bY5EGob3qbSCvzsr47thqV5Bu8SAs= 67 | - secure: YX8OQAVH+mvf4pkw5TEVYeIGc6dv78r6xxTEk7J7dI2K4oQR65dh0mwbkE6kYPVwV+RsMIiFkpgSfAnmyBL5zidNoFS5ksLoIXLVw7hvvUHMyx5cPDhm2GkVoKXXnY/xK6MwZpxd2MF1KOB3Dp3UMpJYSFbNEHusQD3MOnuPIkk= 68 | - secure: Gt8vsZsSU1/f1FIfThCn0Rui9+iGTkMUi7aXtbQgMIXsBHavucggMzIAi224vV+wyCIONkpjrhYYz2ghIHWMWLjtMOm3iFlXAl/BmHHyB9AzdWiJ6jFeLvexo9aBSIfPg855C1GatG4K6CoFpoOWj17ocFa7uITxlNiMCebRqXk= 69 | - secure: D9daPoJr6RZ9GxhDR9Q5WtAIo1k9MD3+rD4IUqVRWF686XEz+/Yk2Cvuq7ZjS7U0Koru66km4sB+LNLjhdZQtbQW4QujIzrldV8jyrCTQzE2UmnhkkkyxztsoRSAIhfNh/yMjuwRf9YO1FhWhGOM/UOF9sCCnj/qr4yZbZqhniI= 70 | - secure: CLhR4V1oMD4NfFky48Y/IsXrgvLujf5kWrQSC/UeQ54vkrMm7Xyqj77SJhN/lmooRoWbaBeeIqVqdzy7jrEkQ2qvksovli19LesPJzZ4wJ0/024XnhyQtsWslYNwYVyIjgpsr7KIP12mjdU0cE9OKxrYHJHZf0Phr7GKNz9d6RI= 71 | - secure: WNhnp1Pt5TkqqiNMc5JTHNXvI3Xgx0LsM8Er40lxk4REq8eHoOycFeKCMn7Y0aPyB4aK+6CUAWcZ/LT+CbZ/BD/AXnXkWeKT4LELGWpeuLzUD9Z4jrZiBUVIVbse+D55ljtY+RfZzo1Ewf1N1dgaIvS2nZKiFLHz0CRGwQaMUNk= 72 | - secure: Cnm8rshB2HFxkS7aED3GcmTrSb6n2LWb/THBJaab8l3IbrNIvd7+zP1QCRhedwxF6U3KfYRYwA4g4kAZL2QO1S1nioKNzxAqeJQ0/FhlNQ+JDeCIm8BfvQrS6Bn2W5X8rUcrXsTB8wpYyu4+CDg8QMSRvXdahQaemEl3YhsnXdQ= 73 | - secure: FMHPE4eUlMyfHb6qFOTu7gL/LuOcbjOmLPQQ6hBQwlHUJkJLiSjKNNhsoxooUsBQq9kEnzk+YSiNn5+IDCPMGE9iKslnAkJh+ehyjtGn3Zd0vK/jHpP2Gg9eZ3XJ5CJjjQmLkgkfvGC2zuOVXn1nJ2uxDDRfEB4c4gWzqQ8uE8c= 74 | - secure: Cqz5a1XHnfE/cSTiUZOalui9B992FGT+UUVbnIIG8x1A+7QvCYJssKIuTXz8/zXxNM6ML0VhpqSPgNgZMNHMc3fsXosbuxzp4w1a3uyZZVwPMup07iI3BE4FnxGN43Sv1n9gy7m98cAJfDv7mbgFyxeKf4CGmE5uu/eTuYQqoKI= 75 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "[]" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright [yyyy] [name of copyright owner] 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing to Opscode Cookbooks 2 | 3 | We are glad you want to contribute to Opscode Cookbooks! The first 4 | step is the desire to improve the project. 5 | 6 | You can find the answers to additional frequently asked questions 7 | [on the wiki](http://wiki.opscode.com/display/chef/How+to+Contribute). 8 | 9 | You can find additional information about 10 | [contributing to cookbooks](http://wiki.opscode.com/display/chef/How+to+Contribute+to+Opscode+Cookbooks) 11 | on the wiki as well. 12 | 13 | ## Quick-contribute 14 | 15 | * Create an account on our [bug tracker](http://tickets.opscode.com) 16 | * Sign our contributor agreement (CLA) 17 | [ online](https://secure.echosign.com/public/hostedForm?formid=PJIF5694K6L) 18 | (keep reading if you're contributing on behalf of your employer) 19 | * Create a ticket for your change on the 20 | [bug tracker](http://tickets.opscode.com) 21 | * Link to your patch as a rebased git branch or pull request from the 22 | ticket 23 | * Resolve the ticket as fixed 24 | 25 | We regularly review contributions and will get back to you if we have 26 | any suggestions or concerns. 27 | 28 | ## The Apache License and the CLA/CCLA 29 | 30 | Licensing is very important to open source projects, it helps ensure 31 | the software continues to be available under the terms that the author 32 | desired. Chef uses the Apache 2.0 license to strike a balance between 33 | open contribution and allowing you to use the software however you 34 | would like to. 35 | 36 | The license tells you what rights you have that are provided by the 37 | copyright holder. It is important that the contributor fully 38 | understands what rights they are licensing and agrees to them. 39 | Sometimes the copyright holder isn't the contributor, most often when 40 | the contributor is doing work for a company. 41 | 42 | To make a good faith effort to ensure these criteria are met, Opscode 43 | requires a Contributor License Agreement (CLA) or a Corporate 44 | Contributor License Agreement (CCLA) for all contributions. This is 45 | without exception due to some matters not being related to copyright 46 | and to avoid having to continually check with our lawyers about small 47 | patches. 48 | 49 | It only takes a few minutes to complete a CLA, and you retain the 50 | copyright to your contribution. 51 | 52 | You can complete our contributor agreement (CLA) 53 | [ online](https://secure.echosign.com/public/hostedForm?formid=PJIF5694K6L). 54 | If you're contributing on behalf of your employer, have your employer 55 | fill out our 56 | [Corporate CLA](https://secure.echosign.com/public/hostedForm?formid=PIE6C7AX856) 57 | instead. 58 | 59 | ## Ticket Tracker (JIRA) 60 | 61 | The [ticket tracker](http://tickets.opscode.com) is the most important 62 | documentation for the code base. It provides significant historical 63 | information, such as: 64 | 65 | * Which release a bug fix is included in 66 | * Discussion regarding the design and merits of features 67 | * Error output to aid in finding similar bugs 68 | 69 | Each ticket should aim to fix one bug or add one feature. 70 | 71 | ## Using git 72 | 73 | You can get a quick copy of the repository for this cookbook by 74 | running `git clone 75 | git://github.com/opscode-coobkooks/COOKBOOKNAME.git`. 76 | 77 | For collaboration purposes, it is best if you create a Github account 78 | and fork the repository to your own account. Once you do this you will 79 | be able to push your changes to your Github repository for others to 80 | see and use. 81 | 82 | If you have another repository in your GitHub account named the same 83 | as the cookbook, we suggest you suffix the repository with -cookbook. 84 | 85 | ### Branches and Commits 86 | 87 | You should submit your patch as a git branch named after the ticket, 88 | such as COOK-1337. This is called a _topic branch_ and allows users to 89 | associate a branch of code with the ticket. 90 | 91 | It is a best practice to have your commit message have a _summary 92 | line_ that includes the ticket number, followed by an empty line and 93 | then a brief description of the commit. This also helps other 94 | contributors understand the purpose of changes to the code. 95 | 96 | [COOK-1757] - platform_family and style 97 | 98 | * use platform_family for platform checking 99 | * update notifies syntax to "resource_type[resource_name]" instead of 100 | resources() lookup 101 | * COOK-692 - delete config files dropped off by packages in conf.d 102 | * dropped debian 4 support because all other platforms have the same 103 | values, and it is older than "old stable" debian release 104 | 105 | Remember that not all users use Chef in the same way or on the same 106 | operating systems as you, so it is helpful to be clear about your use 107 | case and change so they can understand it even when it doesn't apply 108 | to them. 109 | 110 | ### Github and Pull Requests 111 | 112 | All of Opscode's open source cookbook projects are available on 113 | [Github](http://www.github.com/opscode-cookbooks). 114 | 115 | We don't require you to use Github, and we will even take patch diffs 116 | attached to tickets on the tracker. However Github has a lot of 117 | convenient features, such as being able to see a diff of changes 118 | between a pull request and the main repository quickly without 119 | downloading the branch. 120 | 121 | If you do choose to use a pull request, please provide a link to the 122 | pull request from the ticket __and__ a link to the ticket from the 123 | pull request. Because pull requests only have two states, open and 124 | closed, we can't easily filter pull requests that are waiting for a 125 | reply from the author for various reasons. 126 | 127 | ### More information 128 | 129 | Additional help with git is available on the 130 | [Working with Git](http://wiki.opscode.com/display/chef/Working+with+Git) 131 | wiki page. 132 | 133 | ## Functional and Unit Tests 134 | 135 | This cookbook is set up to run tests under 136 | [Opscode's test-kitchen](https://github.com/opscode/test-kitchen). It 137 | uses minitest-chef to run integration tests after the node has been 138 | converged to verify that the state of the node. 139 | 140 | Test kitchen should run completely without exception using the default 141 | [baseboxes provided by Opscode](https://github.com/opscode/bento). 142 | Because Test Kitchen creates VirtualBox machines and runs through 143 | every configuration in the Kitchenfile, it may take some time for 144 | these tests to complete. 145 | 146 | If your changes are only for a specific recipe, run only its 147 | configuration with Test Kitchen. If you are adding a new recipe, or 148 | other functionality such as a LWRP or definition, please add 149 | appropriate tests and ensure they run with Test Kitchen. 150 | 151 | If any don't pass, investigate them before submitting your patch. 152 | 153 | Any new feature should have unit tests included with the patch with 154 | good code coverage to help protect it from future changes. Similarly, 155 | patches that fix a bug or regression should have a _regression test_. 156 | Simply put, this is a test that would fail without your patch but 157 | passes with it. The goal is to ensure this bug doesn't regress in the 158 | future. Consider a regular expression that doesn't match a certain 159 | pattern that it should, so you provide a patch and a test to ensure 160 | that the part of the code that uses this regular expression works as 161 | expected. Later another contributor may modify this regular expression 162 | in a way that breaks your use cases. The test you wrote will fail, 163 | signalling to them to research your ticket and use case and accounting 164 | for it. 165 | 166 | If you need help writing tests, please ask on the Chef Developer's 167 | mailing list, or the #chef-hacking IRC channel. 168 | 169 | ## Code Review 170 | 171 | Opscode regularly reviews code contributions and provides suggestions 172 | for improvement in the code itself or the implementation. 173 | 174 | We find contributions by searching the ticket tracker for _resolved_ 175 | tickets with a status of _fixed_. If we have feedback we will reopen 176 | the ticket and you should resolve it again when you've made the 177 | changes or have a response to our feedback. When we believe the patch 178 | is ready to be merged, we will tag the _Code Reviewed_ field with 179 | _Reviewed_. 180 | 181 | Depending on the project, these tickets are then merged within a week 182 | or two, depending on the current release cycle. 183 | 184 | ## Release Cycle 185 | 186 | The versioning for Opscode Cookbook projects is X.Y.Z. 187 | 188 | * X is a major release, which may not be fully compatible with prior 189 | major releases 190 | * Y is a minor release, which adds both new features and bug fixes 191 | * Z is a patch release, which adds just bug fixes 192 | 193 | A released version of a cookbook will end in an even number, e.g. 194 | "1.2.4" or "0.8.0". When development for the next version of the 195 | cookbook begins, the "Z" patch number is incremented to the next odd 196 | number, however the next release of the cookbook may be a major or 197 | minor incrementing version. 198 | 199 | Releases of Opscode's cookbooks are usually announced on the Chef user 200 | mailing list. Releases of several cookbooks may be batched together 201 | and announced on the [Opscode Blog](http://www.opscode.com/blog). 202 | 203 | ## Working with the community 204 | 205 | These resources will help you learn more about Chef and connect to 206 | other members of the Chef community: 207 | 208 | * [chef](http://lists.opscode.com/sympa/info/chef) and 209 | [chef-dev](http://lists.opscode.com/sympa/info/chef-dev) mailing 210 | lists 211 | * #chef and #chef-hacking IRC channels on irc.freenode.net 212 | * [Community Cookbook site](http://community.opscode.com) 213 | * [Chef wiki](http://wiki.opscode.com/display/chef) 214 | * Opscode Chef [product page](http://www.opscode.com/chef) 215 | 216 | 217 | ## Cookbook Contribution Do's and Don't's 218 | 219 | Please do include tests for your contribution. If you need help, ask 220 | on the 221 | [chef-dev mailing list](http://lists.opscode.com/sympa/info/chef-dev) 222 | or the 223 | [#chef-hacking IRC channel](http://community.opscode.com/chat/chef-hacking). 224 | Not all platforms that a cookbook supports may be supported by Test 225 | Kitchen. Please provide evidence of testing your contribution if it 226 | isn't trivial so we don't have to duplicate effort in testing. Chef 227 | 10.14+ "doc" formatted output is sufficient. 228 | 229 | Please do indicate new platform (families) or platform versions in the 230 | commit message, and update the relevant ticket. 231 | 232 | If a contribution adds new platforms or platform versions, indicate 233 | such in the body of the commit message(s), and update the relevant 234 | COOK ticket. When writing commit messages, it is helpful for others if 235 | you indicate the COOK ticket. For example: 236 | 237 | git commit -m '[COOK-1041] - Updated pool resource to correctly 238 | delete.' 239 | 240 | Please do use [foodcritic](http://acrmp.github.com/foodcritic) to 241 | lint-check the cookbook. Except FC007, it should pass all correctness 242 | rules. FC007 is okay as long as the dependent cookbooks are *required* 243 | for the default behavior of the cookbook, such as to support an 244 | uncommon platform, secondary recipe, etc. 245 | 246 | Please do ensure that your changes do not break or modify behavior for 247 | other platforms supported by the cookbook. For example if your changes 248 | are for Debian, make sure that they do not break on CentOS. 249 | 250 | Please do not modify the version number in the metadata.rb, Opscode 251 | will select the appropriate version based on the release cycle 252 | information above. 253 | 254 | Please do not update the CHANGELOG.md for a new version. Not all 255 | changes to a cookbook may be merged and released in the same versions. 256 | Opscode will update the CHANGELOG.md when releasing a new version of 257 | the cookbook. 258 | --------------------------------------------------------------------------------