From c5301821f53307f3d2c995dca35c31005e80ea91 Mon Sep 17 00:00:00 2001 From: Gael Chamoulaud Date: Thu, 19 Feb 2015 14:05:28 +0100 Subject: [PATCH] Update rabbitmq to 654f3433aaa3c7abaebb0fb2c4574e1ce5da0fcb 654f3433aaa3c7abaebb0fb2c4574e1ce5da0fcb Merge pull request #304 from raphink/dev/unscoped_template_vars a7809a2bd07e3afd68dccf09ff1dbb3c1323bb88 Fix unscoped template variables 9c40d7f28285f5601aea1e025634e7360ff8aa9a Merge pull request #301 from dalees/bug/enable-ssl-versions-2 ae66ee8307f1e563bc22c79949b527939c4aa0f0 Updating rspec tests for ssl_version changes, whitespace and rabbitmq_management version block 4dcfdf510b60887db25eca48165125c4d6956198 Bugfix for ssl_versions in rabbitmq.config so Erlang/RabbitMQ respect them. c47a8becbd227f40d43876b2b48da7b0a2b435c1 Merge pull request #298 from syseleven/MODULES-1691 f2b79c985d16e30c9b87034b8530491db745eb95 SSL option in rabbitmqadmin.conf is broken 5280e6629411fc02582f744f4bc379a2fe002c88 Merge pull request #297 from bogdando/fix_MODULES-1673 177e3e962fdaf16fd1b92e3343ef988bf0baabd7 Merge pull request #296 from jtopjian/enable-ssl-versions-2 bbac2749e91553b6644e97bdd3544a3d187df894 Fix rabbitmq-env.conf parameters 5675b38fbdc0d13c3d3a9b4ed6bb67091cad2ca6 Revised SSL versions documentation 35bb069bb77bc770fbd29edfc0070b41a0d92a85 Added ssl_versions parameter 52d35576edf38c1e56d34cae14607ff5a6b24861 Merge pull request #295 from sodabrew/patch-1 384892af00754e014b8a8fe9224a524cc688e349 Merge pull request #294 from bogdando/fix_MODULES-1650 b39952affb067ed6781276ac2ca268d71df90a4f Merge pull request #293 from deltaroe/master e8dbe8d37d6c9b5377eb9434766884236e4d8658 Merge pull request #292 from bogdando/fix3_MODULES_1452 ac67949e31a13d9cd2512cce80b8677b16d56b02 Merge pull request #290 from jtopjian/fix-pin-conditional da9c7a8ba4f1cc96569623cb9b3562f33925d917 Merge pull request #287 from erhudy/master 4657e5777ed0d7eaf94240ce1d5ce19ca25eee5e Merge pull request #269 from Mayflower/master d37c9ab55d39784156f794b36cad3180516351d7 Idiomatic syntax for should_policy and should_vhost 966e0b50223d7e19275af7d0a99328728a31af3c Add retries for non transient file transfer errors cf301012f94162cfb9566ecc77f1e66f4189a23f Merge pull request #289 from bogdando/fix-MODULES-1631 0813f47f80e134e03d3b112b7bfb9904537edec5 Merge pull request #288 from blkperl/fix_cluster_docs 0be89ec3ada988948b12d7fc66c1a9a0cf534bac Documentation update for ssl_only 9b23a904040cee5b1e24dcef0c8ae0602123ccb6 Make rabbitmq providers to retry the commands f530a5f270fb1ba6c4675e77a1814ca4025cee59 Fix pin conditional ced14e71fe5e281403c20681321995d1e19e6f6a Do not enforce the source value for yum provider da99e169468eceec3f6bca6c8fcb3dbb2118a59d Update cluster example to include required parameters 247b6e049d1751ab58f122e037162aeb98699542 - moved the parenthesis before map to the end so that the map works on the array and then the set is created from that, instead of map coercing the set to an array, which breaks things that call Set#add - switching back to the previous more concise expression form e709ba7271ede8c58155cdbc14f15da87519c04f my first set of changes for the user tag idempotence issue 1cc2e54731a7456123cc05c40d9565e9d2f3fa99 Merge pull request #286 from cmurphy/release aaab4f45c13b689a379f5c22902efc05c6af7848 Prepare 5.0.0 release cfd3d2be07e4c95e749194addd0cebd42b3173bc Merge pull request #285 from cmurphy/rm_27 bdf9453a77560d31ddf88e8bff9195b1aed53bf6 Merge pull request #284 from cmurphy/remove_deprecations 931a6d4b294216f1896c99f12f5aab0102f38e07 Stop claiming to support Puppet 2.7. a2f802cc17aae331663f640337d0f2217c3e438f Add documentation for the new resources d998f948fd4a5001b85fcbf4c40b3a78f08ac2f6 Add new resource rabbitmq_binding ebc20c216d6c294a10b5ae015495fb404a878288 Add new resource rabbitmq_queue 0c061fbd46806491c1b9dc1de2f842a3844d28da Remove deprecated parameters fd13a5a4fe0b8c2b9e2d243e62255e22cec84e28 Merge pull request #282 from cmurphy/cookie 7a8951d52b31983f263dd20a2caa98bc3f92214e Update README 780b63801b7ce7987d22b709597e85f98338636c Stop setting a default cookie 5c485b8cdde48746a27598c9ae1e84e87c79707f Replace erlang cookie fact with type and provider 04145c1c7e45a899536a557e6ac36478b0fcbdaa Merge pull request #281 from cmurphy/alternative_253 cf5d62f089d2e057a17bf401a57e4877db60e1eb Merge pull request #283 from cmurphy/ldap d6411ac663b5b96a03d80137b4e4d5c20bf69be5 Put rabbitmqadmin.conf in /etc/rabbitmq 5aea1f115a59515f57e34e0f3b6a6ec24d3c9274 create /tmp/.rabbitmqadmin.conf 3bb4d15f8d0b9a7db6fc73e020471a2dd042a238 Fix lint errors in ldap_user_dn_example parameter ac046ee440e3444e7fccae90e22562a9cd5c06c7 Merge pull request #280 from cmurphy/ssl 26a74aea49c544f303eb760680546fba92d2f3ad Merge pull request #263 from cmurphy/update_travis 2ece861419fb49ef15848840d507155760af2f7a Installation of the rabbitmqadmin script fails when SSL is enabled. This is fixed by using ::ssl_management_port when SSL is enabled. 325de42b13fbe12e173c3b089bdea3fbf8975459 Merge pull request #266 from nibalizer/beaker_vhost 3741e869a240a2402c6bb8b78660ba2963f2c88c Merge pull request #2 from cmurphy/fix_266 43906f55490af151902235f75fd98b27b76d9602 Improve rabbitmq type acceptance tests f7306ff64216c6216d9d2a00222dc70b743843ff Merge pull request #276 from cmurphy/version e1aab42248f809b1dc1b23e977a9253f38a7be73 Merge pull request #275 from cmurphy/change_password edd56fbd286c7f96ffa5b635a963148658ad69a4 Merge pull request #270 from cmurphy/disk-disc c56f338431a0277b183ef055ada7410f54f2766a (MODULES-636) Allow version to be user-defined ed9690211d03be89ff2b961a63797d23206ffe4e Merge pull request #246 from mhamrah/master 6c67f33d08f68e2cda898d0161f5820cd9f32c0e (MODULES-1186) Allow disk as a valid cluster node type ecd41201b51460a1c9f818412795cac43776f470 Fixes for #218 1f11596349caf678a3fa09dbfcd9406d60936426 Validate user paswwords per run ecd7447016ba7f48c65dc1cf5a225d91c63d2788 Merge pull request #209 from queeno/ensure_apt_source be9658589b2be0b12c79a092709e4c9ddc6228e7 Merge pull request #274 from cmurphy/fix_travisci 81dae074c7b165803028f8925fdf4b5a5e833cf2 Separate system and unit test gems 7671f32c13ef4cad0e930d4c33442c5ce797f10a Merge pull request #260 from spuder/patch-1 00503615a9cb2eb330cc2e4ac6f87db298a4ef78 Updates README with epel dependency Issue #260 8086d73aafe4fa93ccd8cfd3b8c49125ed7cde16 Added rspec tests/$manage_repo backward compatible dac9d753f7910a1af6363f9f5a38ac0d897fc52f Beaker tests for vhost and policy 54fdab4389dd411d96b5d530043702ca4774328c Introduced backward compatibility for $manage_repos a5879f4eb93de1c6c769fd93432166f928946a80 Rename variable 'manage_repos' to 'repos_ensure' da246043494871d43a12e88732aeba768f2f2bb8 Added rspec tests for previous commit 4dad6be 34412d10ebebb63c9135978feac3b3a786fd2171 rabbitmq::manage_repos sets 'ensure' in apt::source 00f64721d0977a0b99894e3c41477c2cdb69492e Merge pull request #268 from nibalizer/lint_checks d371eddd6691f0d5eecc9dbae731d55971cb2cd2 Lint now fails on warnings, rocketships aligned f7b1f339500cf5c3350d7f9a50ba67766bd85aaf Merge pull request #254 from misterdorm/pluginparsing 3ff4dd1acbf94eee0124de7d1777395beaec6db9 Merge pull request #245 from ArloL/patch-1 50b9411c1ba6256d7ed4b27f051c5a2b3680bed6 Merge pull request #239 from mattymo/gpgkeycheck ae876f69644e8e8b1edf0b835201509d5e7dbdfd Merge pull request #235 from cyberious/master 983a2aad64426d82f44c4583d60571213b3f60a4 Merge pull request #233 from michalskalski/master f8b9936464ee83c5c7980e390f83a57e4b3db275 Merge pull request #228 from jmoseley/style_fix 40af5f0ea1ef7706f0dd413038dfc2965508856c Merge pull request #225 from alphagov/strip-backslashes e2e70a7768fed8559e13bfb3ce89d5a88750b146 Merge pull request #212 from tayzlor/fix-curl-wget-proxy-localhost 53adb36e1f1bfd27873a1a04cd3578d2c52e6d57 Merge pull request #265 from nibalizer/docs_fix 7d14bac25c0f584a8c3b25624820c9c6756a2299 Docs fixes 11b72f88d39bb070c42e9ffc55fc7d93d69a5164 Merge pull request #264 from nibalizer/remove_comments e654d81ca39da96d101a17cf9d125b07ba7ddb6d Merge pull request #262 from mgagne/rabbitmq_policy 20518b13eff7dc72f661d1a40b39754837d14267 Remove comments referencing redmine and anchors 4ffdb445ee9de9b5caa3ab71df49b771cacd361c Add rabbitmq_policy custom type 918106503e87b873103de383c1eaef408f27c77c Stop testing on 2.7.0 92031d60e383e1b4b982460d2b9a307b84c9ce25 Merge pull request #261 from cmurphy/master cf6457f4dd3c862c139c198a490999033007ca61 Fix spec tests c6d8aac08c21eeaa31ca6faa2b284e9ceaa681f1 Adds clarification that epel is required a53e0c20ba655f48921a79821ddaae76f730425d Merge pull request #256 from laurenrother/summary 112d87ba7ef3c5cb924ed3a5336584eaef630d65 Merge pull request #259 from nibalizer/longer_keyid 945ad581d508cae07e7a824373c2d2a44ba88b20 Use 16char keyid for rabbit repo a6a98e4ab722a01ca47a39ca371eccbcfa4888b6 Remove trailing whitespace 7bddb6111f09efd218bef7500da4a4f9668853a8 Use shorter URL for RabbitMQ documentation 3e0496f6a05f813d48cf7041e8ea7eef51b506b4 Strip backslashes from the output of rabbitmqctl 0bdf72edaf7c4f93141ef8d045f4b9608314092d Add metadata summary per FM-1523 d262edbf4ed3bd11388f2d1d33346099c1e488d7 Use -m flag on rabbitmq-plugins command for managing rabbitmq_plugin resources 61991d76cda34c7af5c98ceb53666a0a2b57fda7 Merge pull request #251 from nibalizer/fix_340 66ffaaf13582d721dd8180cbe40583bc3a93d491 Merge pull request #1 from cmurphy/fix_fix_340 87d39e800c4bf7dbeb24f50e33a9c6a0f575609e Update unit tests to handle new -q flag 7adb3181a20f95f657348e76e208cc73334f2c01 Use -q flag instead of array slices a6b2f8084273a424f64ab8c173cb70c3feef7f43 passing tests 835fc66d7a17ba13cc2dda4fc099a6a2569b847e use rpm for RedHat family c7a1cbb64e325ea1225dce124bb5d2768ce076b4 Output cacertfile value only if it is set 15ec2847ad41fc25ee1b9da369585ccd5c146b0c Optimize check for RHEL GPG key 4d2d9317c0a5c5aca5ceb37338fb8640cd7fa24c Remove puppet_module_install in favor of copy_module_to 69fcc9bb1217868bb650776b73d382bfd0208f9d Make curl and wget not go via a proxy (if one is configured) for installation of the rabbitmq admin CLI b377b82c57712bcd3e32c019f980d8af777d32dc Use warning instead of notify when inform about deprecation. 1f87d17d0cd33566a9264ac6ce55e0cd097341a8 Fix style for puppet-lint failures. Signed-off-by: Gael Chamoulaud --- Puppetfile | 2 +- rabbitmq/.travis.yml | 6 +- rabbitmq/{CHANGELOG => CHANGELOG.md} | 115 ++++-- rabbitmq/Gemfile | 20 +- rabbitmq/README.md | 103 +++++- rabbitmq/Rakefile | 1 + rabbitmq/lib/facter/rabbitmq_erlang_cookie.rb | 16 - .../rabbitmq_binding/rabbitmqadmin.rb | 110 ++++++ .../provider/rabbitmq_erlang_cookie/ruby.rb | 38 ++ .../rabbitmq_exchange/rabbitmqadmin.rb | 19 +- .../rabbitmq_plugin/rabbitmqplugins.rb | 15 +- .../provider/rabbitmq_policy/rabbitmqctl.rb | 119 ++++++ .../provider/rabbitmq_queue/rabbitmqadmin.rb | 105 ++++++ .../provider/rabbitmq_user/rabbitmqctl.rb | 35 +- .../rabbitmq_user_permissions/rabbitmqctl.rb | 15 +- .../provider/rabbitmq_vhost/rabbitmqctl.rb | 11 +- rabbitmq/lib/puppet/provider/rabbitmqctl.rb | 33 ++ rabbitmq/lib/puppet/type/rabbitmq_binding.rb | 96 +++++ .../lib/puppet/type/rabbitmq_erlang_cookie.rb | 22 ++ rabbitmq/lib/puppet/type/rabbitmq_policy.rb | 76 ++++ rabbitmq/lib/puppet/type/rabbitmq_queue.rb | 68 ++++ rabbitmq/lib/puppet/type/rabbitmq_user.rb | 14 +- rabbitmq/manifests/config.pp | 86 ++--- rabbitmq/manifests/init.pp | 61 +++- rabbitmq/manifests/install.pp | 4 +- rabbitmq/manifests/install/rabbitmqadmin.pp | 17 +- rabbitmq/manifests/params.pp | 23 +- rabbitmq/manifests/repo/apt.pp | 10 +- rabbitmq/manifests/repo/rhel.pp | 16 +- rabbitmq/manifests/server.pp | 54 +-- rabbitmq/metadata.json | 51 ++- rabbitmq/spec/acceptance/class_spec.rb | 1 - rabbitmq/spec/acceptance/clustering_spec.rb | 30 +- .../nodesets/ubuntu-server-1310-x64.yml | 11 - rabbitmq/spec/acceptance/policy_spec.rb | 47 +++ rabbitmq/spec/acceptance/user_spec.rb | 38 ++ rabbitmq/spec/acceptance/vhost_spec.rb | 37 ++ rabbitmq/spec/classes/rabbitmq_spec.rb | 339 ++++++++++++++---- rabbitmq/spec/spec_helper_acceptance.rb | 2 +- .../unit/facts/rabbitmq_erlang_cookie_spec.rb | 19 - .../rabbitmq_binding/rabbitmqadmin_spec.rb | 59 +++ .../rabbitmq_exchange/rabbitmqadmin_spec.rb | 6 +- .../rabbitmq_plugin/rabbitmqctl_spec.rb | 26 ++ .../rabbitmq_policy/rabbitmqctl_spec.rb | 114 ++++++ .../rabbitmq_queue/rabbitmqadmin_spec.rb | 60 ++++ .../rabbitmq_user/rabbitmqctl_spec.rb | 81 ++--- .../rabbitmqctl_spec.rb | 36 +- .../rabbitmq_vhost/rabbitmqctl_spec.rb | 6 +- .../unit/puppet/type/rabbitmq_binding_spec.rb | 50 +++ .../unit/puppet/type/rabbitmq_policy_spec.rb | 91 +++++ .../unit/puppet/type/rabbitmq_queue_spec.rb | 60 ++++ rabbitmq/templates/rabbitmq.config.erb | 19 +- rabbitmq/templates/rabbitmqadmin.conf.erb | 7 + 53 files changed, 2069 insertions(+), 431 deletions(-) rename rabbitmq/{CHANGELOG => CHANGELOG.md} (61%) delete mode 100644 rabbitmq/lib/facter/rabbitmq_erlang_cookie.rb create mode 100644 rabbitmq/lib/puppet/provider/rabbitmq_binding/rabbitmqadmin.rb create mode 100644 rabbitmq/lib/puppet/provider/rabbitmq_erlang_cookie/ruby.rb create mode 100644 rabbitmq/lib/puppet/provider/rabbitmq_policy/rabbitmqctl.rb create mode 100644 rabbitmq/lib/puppet/provider/rabbitmq_queue/rabbitmqadmin.rb create mode 100644 rabbitmq/lib/puppet/provider/rabbitmqctl.rb create mode 100644 rabbitmq/lib/puppet/type/rabbitmq_binding.rb create mode 100644 rabbitmq/lib/puppet/type/rabbitmq_erlang_cookie.rb create mode 100644 rabbitmq/lib/puppet/type/rabbitmq_policy.rb create mode 100644 rabbitmq/lib/puppet/type/rabbitmq_queue.rb delete mode 100644 rabbitmq/spec/acceptance/nodesets/ubuntu-server-1310-x64.yml create mode 100644 rabbitmq/spec/acceptance/policy_spec.rb create mode 100644 rabbitmq/spec/acceptance/user_spec.rb create mode 100644 rabbitmq/spec/acceptance/vhost_spec.rb delete mode 100644 rabbitmq/spec/unit/facts/rabbitmq_erlang_cookie_spec.rb create mode 100644 rabbitmq/spec/unit/puppet/provider/rabbitmq_binding/rabbitmqadmin_spec.rb create mode 100644 rabbitmq/spec/unit/puppet/provider/rabbitmq_plugin/rabbitmqctl_spec.rb create mode 100644 rabbitmq/spec/unit/puppet/provider/rabbitmq_policy/rabbitmqctl_spec.rb create mode 100644 rabbitmq/spec/unit/puppet/provider/rabbitmq_queue/rabbitmqadmin_spec.rb create mode 100644 rabbitmq/spec/unit/puppet/type/rabbitmq_binding_spec.rb create mode 100644 rabbitmq/spec/unit/puppet/type/rabbitmq_policy_spec.rb create mode 100644 rabbitmq/spec/unit/puppet/type/rabbitmq_queue_spec.rb create mode 100644 rabbitmq/templates/rabbitmqadmin.conf.erb diff --git a/Puppetfile b/Puppetfile index c9eb4b267..57e377c25 100644 --- a/Puppetfile +++ b/Puppetfile @@ -143,7 +143,7 @@ mod 'qpid', :git => 'https://github.com/dprince/puppet-qpid' mod 'rabbitmq', - :commit => '4832bd61b5b1bfea7c9cc985508e65cd10081652', + :commit => '654f3433aaa3c7abaebb0fb2c4574e1ce5da0fcb', :git => 'https://github.com/puppetlabs/puppetlabs-rabbitmq.git' mod 'redis', diff --git a/rabbitmq/.travis.yml b/rabbitmq/.travis.yml index a40ae502e..0618715a1 100644 --- a/rabbitmq/.travis.yml +++ b/rabbitmq/.travis.yml @@ -1,14 +1,10 @@ --- language: ruby -bundler_args: --without development +bundler_args: --without system_tests script: "bundle exec rake validate && bundle exec rake lint && bundle exec rake spec SPEC_OPTS='--format documentation'" matrix: fast_finish: true include: - - rvm: 1.8.7 - env: PUPPET_GEM_VERSION="~> 2.7.0" FACTER_GEM_VERSION="~> 1.6.0" - - rvm: 1.8.7 - env: PUPPET_GEM_VERSION="~> 2.7.0" FACTER_GEM_VERSION="~> 1.7.0" - rvm: 1.9.3 env: PUPPET_GEM_VERSION="~> 3.0" - rvm: 2.0.0 diff --git a/rabbitmq/CHANGELOG b/rabbitmq/CHANGELOG.md similarity index 61% rename from rabbitmq/CHANGELOG rename to rabbitmq/CHANGELOG.md index 72f74ae25..e254a9c91 100644 --- a/rabbitmq/CHANGELOG +++ b/rabbitmq/CHANGELOG.md @@ -1,18 +1,72 @@ -2014-08-20 - Version 4.1.0 - -Summary: +## 2014-12-22 - Version 5.0.0 + +### Summary + +This release fixes a longstanding security issue where the rabbitmq +erlang cookie was exposed as a fact by managing the cookie with a +provider. It also drops support for Puppet 2.7, adds many features +and fixes several bugs. + +#### Backwards-incompatible Changes + +- Removed the rabbitmq_erlang_cookie fact and replaced the logic to + manage that cookie with a provider. +- Dropped official support for Puppet 2.7 (EOL 9/30/2014 + https://groups.google.com/forum/#!topic/puppet-users/QLguMcLraLE ) +- Changed the default value of $rabbitmq::params::ldap_user_dn_pattern + to not contain a variable +- Removed deprecated parameters: $rabbitmq::cluster_disk_nodes, + $rabbitmq::server::manage_service, and + $rabbitmq::server::config_mirrored_queues + +#### Features + +- Add tcp_keepalive parameter to enable TCP keepalive +- Use https to download rabbitmqadmin tool when $rabbitmq::ssl is true +- Add key_content parameter for offline Debian package installations +- Use 16 character apt key to avoid potential collisions +- Add rabbitmq_policy type, including support for rabbitmq <3.2.0 +- Add rabbitmq::ensure_repo parameter +- Add ability to change rabbitmq_user password +- Allow disk as a valid cluster node type + +#### Bugfixes + +- Avoid attempting to install rabbitmqadmin via a proxy (since it is + downloaded from localhost) +- Optimize check for RHEL GPG key +- Configure ssl_listener in stomp only if using ssl +- Use rpm as default package provider for RedHat, bringing the module in + line with the documented instructions to manage erlang separately and allowing + the default version and source parameters to become meaningful +- Configure cacertfile only if verify_none is not set +- Use -q flag for rabbitmqctl commands to avoid parsing inconsistent + debug output +- Use the -m flag for rabbitmqplugins commands, again to avoid parsing + inconsistent debug output +- Strip backslashes from the rabbitmqctl output to avoid parsing issues +- Fix limitation where version parameter was ignored +- Add /etc/rabbitmq/rabbitmqadmin.conf to fix rabbitmqadmin port usage + when ssl is on +- Fix linter errors and warnings +- Add, update, and fix tests +- Update docs + +## 2014-08-20 - Version 4.1.0 + +### Summary This release adds several new features, fixes bugs, and improves tests and documentation. -Features: +#### Features - Autorequire the rabbitmq-server service in the rabbitmq_vhost type - Add credentials to rabbitmqadmin URL - Added $ssl_only parameter to rabbitmq, rabbitmq::params, and rabbitmq::config - Added property tags to rabbitmq_user provider -Bugfixes: +#### Bugfixes - Fix erroneous commas in rabbitmq::config - Use correct ensure value for the rabbitmq_stomp rabbitmq_plugin - Set HOME env variable to nil when leveraging rabbitmq to remove type error @@ -22,18 +76,18 @@ from Python script - Allow LDAP auth configuration without configuring stomp - Added missing $ssl_verify and $ssl_fail_if_no_peer_cert to rabbitmq::config -2014-05-16 - Version 4.0.0 +## 2014-05-16 - Version 4.0.0 -Summary: +### Summary This release includes many new features and bug fixes. With the exception of erlang management this should be backwards compatible with 3.1.0. -Backwards-incompatible Changes: +#### Backwards-incompatible Changes - erlang_manage was removed. You will need to manage erlang separately. See the README for more information on how to configure this. -Features: +#### Features - Improved SSL support - Add LDAP support - Add ability to manage RabbitMQ repositories @@ -45,7 +99,7 @@ Features: - Allow empty permission fields - Convert existing system tests to beaker acceptance tests. -Bugfixes: +#### Bugfixes - exchanges no longer recreated on each puppet run if non-default vhost is used - Allow port to be UNSET - Re-added rabbitmq::server class @@ -59,40 +113,43 @@ Bugfixes: rabbitmq::install -2013-09-14 - Version 3.1.0 +## 2013-09-14 - Version 3.1.0 -Summary: +### Summary This release focuses on a few small (but critical) bugfixes as well as extends the amount of custom RabbitMQ configuration you can do with the module. -Features: +#### Features - You can now change RabbitMQ 'Config Variables' via the parameter `config_variables`. - You can now change RabbitMQ 'Environment Variables' via the parameter `environment_variables`. - ArchLinux support added. -Fixes: +#### Fixes - Make use of the user/password parameters in rabbitmq_exchange{} - Correct the read/write parameter order on set_permissions/list_permissions as they were reversed. - Make the module pull down 3.1.5 by default. -* 2013-07-18 3.0.0 -Summary: +## 2013-07-18 3.0.0 + +### Summary + This release heavily refactors the RabbitMQ and changes functionality in several key ways. Please pay attention to the new README.md file for details of how to interact with the class now. Puppet 3 and RHEL are now fully supported. The default version of RabbitMQ has changed to a 3.x release. -Bugfixes: +#### Bugfixes + - Improve travis testing options. - Stop reimporting the GPG key on every run on RHEL and Debian. - Fix documentation to make it clear you don't have to set provider => each time. - Reference the standard rabbitmq port in the documentation instead of a custom port. - Fixes to the README formatting. -Features: +#### Features - Refactor the module to fix RHEL support. All interaction with the module is now done through the main rabbitmq class. - Add support for mirrored queues (Only on Debian family distributions currently) @@ -101,39 +158,41 @@ is now done through the main rabbitmq class. - `manage_service`: Boolean to choose if Puppet should manage the service. (For pacemaker/HA setups) - Add SuSE support. -Incompatible Changes: +#### Incompatible Changes + - Rabbitmq::server has been removed and is now rabbitmq::config. You should not use this class directly, only via the main rabbitmq class. -* 2013-04-11 2.1.0 +## 2013-04-11 2.1.0 + - remove puppetversion from rabbitmq.config template - add cluster support - escape resource names in regexp -* 2012-07-31 Jeff McCune 2.0.2 +## 2012-07-31 Jeff McCune 2.0.2 - Re-release 2.0.1 with $EDITOR droppings cleaned up -* 2012-05-03 2.0.0 +## 2012-05-03 2.0.0 - added support for new-style admin users - added support for rabbitmq 2.7.1 -* 2011-06-14 Dan Bode 2.0.0rc1 +## 2011-06-14 Dan Bode 2.0.0rc1 - Massive refactor: - added native types for user/vhost/user_permissions - added apt support for vendor packages - added smoke tests -* 2011-04-08 Jeff McCune 1.0.4 +## 2011-04-08 Jeff McCune 1.0.4 - Update module for RabbitMQ 2.4.1 and rabbitmq-plugin-stomp package. -2011-03-24 1.0.3 +## 2011-03-24 1.0.3 - Initial release to the forge. Reviewed by Cody. Whitespace is good. -2011-03-22 1.0.2 +## 2011-03-22 1.0.2 - Whitespace only fix again... ack '\t' is my friend... -2011-03-22 1.0.1 +## 2011-03-22 1.0.1 - Whitespace only fix. -2011-03-22 1.0.0 +## 2011-03-22 1.0.0 - Initial Release. Manage the package, file and service. diff --git a/rabbitmq/Gemfile b/rabbitmq/Gemfile index 02e632165..12fd363ea 100644 --- a/rabbitmq/Gemfile +++ b/rabbitmq/Gemfile @@ -1,14 +1,18 @@ -source 'https://rubygems.org' +source ENV['GEM_SOURCE'] || "https://rubygems.org" -group :development, :test do - gem 'rake', '10.1.1', :require => false - gem 'rspec-puppet', '>=1.0.0', :require => false +group :development, :unit_tests do + gem 'rake', :require => false + gem 'rspec-puppet', :require => false gem 'puppetlabs_spec_helper', :require => false gem 'puppet-lint', :require => false - gem 'serverspec', :require => false - gem 'beaker', :require => false - gem 'beaker-rspec', :require => false - gem 'pry', :require => false + gem 'simplecov', :require => false + gem 'puppet_facts', :require => false + gem 'json', :require => false +end + +group :system_tests do + gem 'beaker-rspec', :require => false + gem 'serverspec', :require => false end if facterversion = ENV['FACTER_GEM_VERSION'] diff --git a/rabbitmq/README.md b/rabbitmq/README.md index ebf879083..258f9bf13 100644 --- a/rabbitmq/README.md +++ b/rabbitmq/README.md @@ -36,6 +36,7 @@ all features against earlier versions. ###Beginning with rabbitmq + ```puppet include '::rabbitmq' ``` @@ -83,8 +84,8 @@ To use RabbitMQ Environment Variables, use the parameters `environment_variables class { 'rabbitmq': port => '5672', environment_variables => { - 'RABBITMQ_NODENAME' => 'node01', - 'RABBITMQ_SERVICENAME' => 'RabbitMQ' + 'NODENAME' => 'node01', + 'SERVICENAME' => 'RabbitMQ' } } ``` @@ -122,9 +123,11 @@ To use RabbitMQ clustering facilities, use the rabbitmq parameters ```puppet class { 'rabbitmq': - config_cluster => true, - cluster_nodes => ['rabbit1', 'rabbit2'], - cluster_node_type => 'ram', + config_cluster => true, + cluster_nodes => ['rabbit1', 'rabbit2'], + cluster_node_type => 'ram', + erlang_cookie => 'A_SECRET_COOKIE_STRING', + wipe_db_on_cookie_change => true, } ``` @@ -138,7 +141,7 @@ class { 'rabbitmq': * rabbitmq::params: Different configuration data for different systems. * rabbitmq::service: Handles the rabbitmq service. * rabbitmq::repo::apt: Handles apt repo for Debian systems. -* rabbitmq::repo::rhel: Handles yum repo for Redhat systems. +* rabbitmq::repo::rhel: Handles rpm repo for Redhat systems. ###Parameters @@ -146,10 +149,6 @@ class { 'rabbitmq': Boolean, if enabled sets up the management interface/plugin for RabbitMQ. -####`cluster_disk_nodes` - -DEPRECATED AND REPLACED BY CLUSTER_NODES. - ####`cluster_node_type` Choose between disk and ram nodes. @@ -221,6 +220,7 @@ RabbitMQ Environment Variables in rabbitmq_env.config ####`erlang_cookie` The erlang cookie to use for clustering - must be the same between all nodes. +This value has no default and must be set explicitly if using clustering. ###`key_content` @@ -261,7 +261,7 @@ The port for the RabbitMQ management interface. ####`node_ip_address` -The value of RABBITMQ_NODE_IP_ADDRESS in rabbitmq_env.config +The value of NODE_IP_ADDRESS in rabbitmq_env.config ####`package_ensure` @@ -271,7 +271,7 @@ be changed to latest. ####`package_gpg_key` RPM package GPG key to import. Uses source method. Should be a URL for Debian/RedHat -OS family, or a file name for RedHat OS family. +OS family, or a file name for RedHat OS family. Set to http://www.rabbitmq.com/rabbitmq-signing-key-public.asc by default. Note, that `key_content`, if specified, would override this parameter for Debian OS family. @@ -287,6 +287,12 @@ What provider to use to install the package. Where should the package be installed from? +On Debian- and Arch-based systems using the default package provider, +this parameter is ignored and the package is installed from the +rabbitmq repository, if enabled with manage_repo => true, or from the +system repository otherwise. If you want to use dpkg as the +package_provider, you must specify a local package_source. + ####`plugin_dir` Location of RabbitMQ plugins. @@ -314,7 +320,7 @@ Configures the service for using SSL. ####`ssl_only` Configures the service to only use SSL. No cleartext TCP listeners will be created. -Requires that ssl => true also. +Requires that ssl => true and port => UNSET also ####`ssl_cacert` @@ -344,6 +350,12 @@ rabbitmq.config SSL verify setting. rabbitmq.config `fail_if_no_peer_cert` setting. +####`ssl_versions` + +Choose which SSL versions to enable. Example: `['tlsv1.2', 'tlsv1.1']`. + +Note that it is recommended to disable `sslv3` and `tlsv1` to prevent against POODLE and BEAST attacks. Please see the [RabbitMQ SSL](https://www.rabbitmq.com/ssl.html) documentation for more information. + ####`stomp_port` The port to use for Stomp. @@ -360,6 +372,11 @@ Boolean to enable TCP connection keepalive for RabbitMQ service. Sets the version to install. +On Debian- and Arch-based operating systems, the version parameter is +ignored and the latest version is installed from the rabbitmq +repository, if enabled with manage_repo => true, or from the system +repository otherwise. + ####`wipe_db_on_cookie_change` Boolean to determine if we should DESTROY AND DELETE the RabbitMQ database. @@ -408,6 +425,35 @@ rabbitmq_exchange { 'myexchange@myhost': } ``` +### rabbitmq\_queue + +```puppet +rabbitmq_queue { 'myqueue@myhost': + user => 'dan', + password => 'bar', + durable => true, + auto_delete => false, + arguments => { + x-message-ttl => 123, + x-dead-letter-exchange => 'other' + }, + ensure => present, +} +``` + +### rabbitmq\_binding + +```puppet +rabbitmq_binding { 'myexchange@myqueue@myhost': + user => 'dan', + password => 'bar', + destination_type => 'queue', + routing_key => '#', + arguments => {}, + ensure => present, +} +``` + ### rabbitmq\_user\_permissions ```puppet @@ -418,6 +464,20 @@ rabbitmq_user_permissions { 'dan@myhost': } ``` +### rabbitmq\_policy + +```puppet +rabbitmq_policy { 'ha-all@myhost': + pattern => '.*', + priority => 0, + applyto => 'all', + definition => { + 'ha-mode' => 'all', + 'ha-sync-mode' => 'automatic', + }, +} +``` + ### rabbitmq\_plugin query all currently enabled plugins `$ puppet resource rabbitmq_plugin` @@ -428,20 +488,33 @@ rabbitmq_plugin {'rabbitmq_stomp': } ``` +### rabbitmq\_erlang\_cookie + +This is essentially a private type used by the rabbitmq::config class +to manage the erlang cookie. It replaces the rabbitmq_erlang_cookie fact +from earlier versions of this module. It manages the content of the cookie +usually located at /var/lib/rabbitmq/.erlang.cookie, which includes +stopping the rabbitmq service and wiping out the database at +/var/lib/rabbitmq/mnesia if the user agrees to it. We don't recommend using +this type directly. + ##Limitations -This module has been built on and tested against Puppet 2.7 and higher. +This module has been built on and tested against Puppet 3.x. The module has been tested on: * RedHat Enterprise Linux 5/6 * Debian 6/7 * CentOS 5/6 -* Ubuntu 12.04 +* Ubuntu 12.04/14.04 Testing on other platforms has been light and cannot be guaranteed. ### Module dependencies + +If running CentOS/RHEL, and using the yum provider, ensure the epel repo is present. + To have a suitable erlang version installed on RedHat and Debian systems, you have to install another puppet module from http://forge.puppetlabs.com/garethr/erlang with: diff --git a/rabbitmq/Rakefile b/rabbitmq/Rakefile index 5868545f2..558b57a1e 100644 --- a/rabbitmq/Rakefile +++ b/rabbitmq/Rakefile @@ -7,4 +7,5 @@ PuppetLint.configuration.send('disable_class_inherits_from_params_class') PuppetLint.configuration.send('disable_class_parameter_defaults') PuppetLint.configuration.send('disable_documentation') PuppetLint.configuration.send('disable_single_quote_string_with_variables') +PuppetLint.configuration.fail_on_warnings = true PuppetLint.configuration.ignore_paths = ["spec/**/*.pp", "pkg/**/*.pp"] diff --git a/rabbitmq/lib/facter/rabbitmq_erlang_cookie.rb b/rabbitmq/lib/facter/rabbitmq_erlang_cookie.rb deleted file mode 100644 index 474e12885..000000000 --- a/rabbitmq/lib/facter/rabbitmq_erlang_cookie.rb +++ /dev/null @@ -1,16 +0,0 @@ -# Fact: rabbitmq_erlang_cookie -# -# Purpose: To determine the current erlang cookie value. -# -# Resolution: Returns the cookie. -Facter.add(:rabbitmq_erlang_cookie) do - confine :osfamily => %w[Debian RedHat Suse] - - setcode do - if File.exists?('/var/lib/rabbitmq/.erlang.cookie') - File.read('/var/lib/rabbitmq/.erlang.cookie') - else - nil - end - end -end diff --git a/rabbitmq/lib/puppet/provider/rabbitmq_binding/rabbitmqadmin.rb b/rabbitmq/lib/puppet/provider/rabbitmq_binding/rabbitmqadmin.rb new file mode 100644 index 000000000..e0eebd025 --- /dev/null +++ b/rabbitmq/lib/puppet/provider/rabbitmq_binding/rabbitmqadmin.rb @@ -0,0 +1,110 @@ +require 'json' +require 'puppet' +Puppet::Type.type(:rabbitmq_binding).provide(:rabbitmqadmin) do + + if Puppet::PUPPETVERSION.to_f < 3 + commands :rabbitmqctl => 'rabbitmqctl' + commands :rabbitmqadmin => '/usr/local/bin/rabbitmqadmin' + else + has_command(:rabbitmqctl, 'rabbitmqctl') do + environment :HOME => "/tmp" + end + has_command(:rabbitmqadmin, '/usr/local/bin/rabbitmqadmin') do + environment :HOME => "/tmp" + end + end + defaultfor :feature => :posix + + def should_vhost + if @should_vhost + @should_vhost + else + @should_vhost = resource[:name].split('@').last + end + end + + def self.all_vhosts + vhosts = [] + rabbitmqctl('list_vhosts', '-q').split(/\n/).collect do |vhost| + vhosts.push(vhost) + end + vhosts + end + + def self.all_bindings(vhost) + rabbitmqctl('list_bindings', '-q', '-p', vhost, 'source_name', 'destination_name', 'destination_kind', 'routing_key', 'arguments').split(/\n/) + end + + def self.instances + resources = [] + all_vhosts.each do |vhost| + all_bindings(vhost).collect do |line| + source_name, destination_name, destination_type, routing_key, arguments = line.split(/\t/) + # Convert output of arguments from the rabbitmqctl command to a json string. + if !arguments.nil? + arguments = arguments.gsub(/^\[(.*)\]$/, "").gsub(/\{("(?:.|\\")*?"),/, '{\1:').gsub(/\},\{/, ",") + if arguments == "" + arguments = '{}' + end + else + arguments = '{}' + end + if (source_name != '') + binding = { + :destination_type => destination_type, + :routing_key => routing_key, + :arguments => JSON.parse(arguments), + :ensure => :present, + :name => "%s@%s@%s" % [source_name, destination_name, vhost], + } + resources << new(binding) if binding[:name] + end + end + end + resources + end + + def self.prefetch(resources) + packages = instances + resources.keys.each do |name| + if provider = packages.find{ |pkg| pkg.name == name } + resources[name].provider = provider + end + end + end + + def exists? + @property_hash[:ensure] == :present + end + + def create + vhost_opt = should_vhost ? "--vhost=#{should_vhost}" : '' + name = resource[:name].split('@').first + destination = resource[:name].split('@')[1] + arguments = resource[:arguments] + if arguments.nil? + arguments = {} + end + rabbitmqadmin('declare', + 'binding', + vhost_opt, + "--user=#{resource[:user]}", + "--password=#{resource[:password]}", + "source=#{name}", + "destination=#{destination}", + "arguments=#{arguments.to_json}", + "routing_key=#{resource[:routing_key]}", + "destination_type=#{resource[:destination_type]}" + ) + @property_hash[:ensure] = :present + end + + def destroy + vhost_opt = should_vhost ? "--vhost=#{should_vhost}" : '' + name = resource[:name].split('@').first + destination = resource[:name].split('@')[1] + rabbitmqadmin('delete', 'binding', vhost_opt, "--user=#{resource[:user]}", "--password=#{resource[:password]}", "source=#{name}", "destination_type=#{resource[:destination_type]}", "destination=#{destination}") + @property_hash[:ensure] = :absent + end + +end diff --git a/rabbitmq/lib/puppet/provider/rabbitmq_erlang_cookie/ruby.rb b/rabbitmq/lib/puppet/provider/rabbitmq_erlang_cookie/ruby.rb new file mode 100644 index 000000000..6e05b7811 --- /dev/null +++ b/rabbitmq/lib/puppet/provider/rabbitmq_erlang_cookie/ruby.rb @@ -0,0 +1,38 @@ +require 'puppet' +require 'set' +Puppet::Type.type(:rabbitmq_erlang_cookie).provide(:ruby) do + + defaultfor :feature => :posix + has_command(:puppet, 'puppet') do + environment :PATH => '/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin' + end + + def exists? + # Hack to prevent the create method from being called. + # We never need to create or destroy this resource, only change its value + true + end + + def content=(value) + if resource[:force] == :true # Danger! + puppet('resource', 'service', resource[:service_name], 'ensure=stopped') + FileUtils.rm_rf('/var/lib/rabbitmq/mnesia') + File.open(resource[:path], 'w') do |cookie| + cookie.chmod(0400) + cookie.write(value) + end + FileUtils.chown('rabbitmq', 'rabbitmq', resource[:path]) + else + fail("The current erlang cookie needs to change. In order to do this the RabbitMQ database needs to be wiped. Please set force => true to allow this to happen automatically.") + end + end + + def content + if File.exists?(resource[:path]) + File.read(resource[:path]) + else + '' + end + end + +end diff --git a/rabbitmq/lib/puppet/provider/rabbitmq_exchange/rabbitmqadmin.rb b/rabbitmq/lib/puppet/provider/rabbitmq_exchange/rabbitmqadmin.rb index 0fa354db0..f9ea3d286 100644 --- a/rabbitmq/lib/puppet/provider/rabbitmq_exchange/rabbitmqadmin.rb +++ b/rabbitmq/lib/puppet/provider/rabbitmq_exchange/rabbitmqadmin.rb @@ -1,5 +1,6 @@ require 'puppet' -Puppet::Type.type(:rabbitmq_exchange).provide(:rabbitmqadmin) do +require File.expand_path(File.join(File.dirname(__FILE__), '..', 'rabbitmqctl')) +Puppet::Type.type(:rabbitmq_exchange).provide(:rabbitmqadmin, :parent => Puppet::Provider::Rabbitmqctl) do if Puppet::PUPPETVERSION.to_f < 3 commands :rabbitmqctl => 'rabbitmqctl' @@ -24,7 +25,11 @@ def should_vhost def self.all_vhosts vhosts = [] - parse_command(rabbitmqctl('list_vhosts')).collect do |vhost| + parse_command( + self.run_with_retries { + rabbitmqctl('list_vhosts') + } + ).collect do |vhost| vhosts.push(vhost) end vhosts @@ -32,7 +37,11 @@ def self.all_vhosts def self.all_exchanges(vhost) exchanges = [] - parse_command(rabbitmqctl('list_exchanges', '-p', vhost, 'name', 'type')) + parse_command( + self.run_with_retries { + rabbitmqctl('list_exchanges', '-p', vhost, 'name', 'type') + } + ) end def self.parse_command(cmd_output) @@ -82,14 +91,14 @@ def exists? def create vhost_opt = should_vhost ? "--vhost=#{should_vhost}" : '' name = resource[:name].split('@')[0] - rabbitmqadmin('declare', 'exchange', vhost_opt, "--user=#{resource[:user]}", "--password=#{resource[:password]}", "name=#{name}", "type=#{resource[:type]}") + rabbitmqadmin('declare', 'exchange', vhost_opt, "--user=#{resource[:user]}", "--password=#{resource[:password]}", "name=#{name}", "type=#{resource[:type]}", '-c', '/etc/rabbitmq/rabbitmqadmin.conf') @property_hash[:ensure] = :present end def destroy vhost_opt = should_vhost ? "--vhost=#{should_vhost}" : '' name = resource[:name].split('@')[0] - rabbitmqadmin('delete', 'exchange', vhost_opt, "--user=#{resource[:user]}", "--password=#{resource[:password]}", "name=#{name}") + rabbitmqadmin('delete', 'exchange', vhost_opt, "--user=#{resource[:user]}", "--password=#{resource[:password]}", "name=#{name}", '-c', '/etc/rabbitmq/rabbitmqadmin.conf') @property_hash[:ensure] = :absent end diff --git a/rabbitmq/lib/puppet/provider/rabbitmq_plugin/rabbitmqplugins.rb b/rabbitmq/lib/puppet/provider/rabbitmq_plugin/rabbitmqplugins.rb index eefc9fb25..7ab5420c3 100644 --- a/rabbitmq/lib/puppet/provider/rabbitmq_plugin/rabbitmqplugins.rb +++ b/rabbitmq/lib/puppet/provider/rabbitmq_plugin/rabbitmqplugins.rb @@ -1,4 +1,5 @@ -Puppet::Type.type(:rabbitmq_plugin).provide(:rabbitmqplugins) do +require File.expand_path(File.join(File.dirname(__FILE__), '..', 'rabbitmqctl')) +Puppet::Type.type(:rabbitmq_plugin).provide(:rabbitmqplugins, :parent => Puppet::Provider::Rabbitmqctl) do if Puppet::PUPPETVERSION.to_f < 3 if Facter.value(:osfamily) == 'RedHat' @@ -21,8 +22,10 @@ defaultfor :feature => :posix def self.instances - rabbitmqplugins('list', '-E').split(/\n/).map do |line| - if line.split(/\s+/)[1] =~ /^(\S+)$/ + self.run_with_retries { + rabbitmqplugins('list', '-E', '-m') + }.split(/\n/).map do |line| + if line =~ /^(\S+)$/ new(:name => $1) else raise Puppet::Error, "Cannot parse invalid plugins line: #{line}" @@ -39,8 +42,10 @@ def destroy end def exists? - rabbitmqplugins('list', '-E').split(/\n/).detect do |line| - line.split(/\s+/)[1].match(/^#{resource[:name]}$/) + self.class.run_with_retries { + rabbitmqplugins('list', '-E', '-m') + }.split(/\n/).detect do |line| + line.match(/^#{resource[:name]}$/) end end diff --git a/rabbitmq/lib/puppet/provider/rabbitmq_policy/rabbitmqctl.rb b/rabbitmq/lib/puppet/provider/rabbitmq_policy/rabbitmqctl.rb new file mode 100644 index 000000000..7e7329580 --- /dev/null +++ b/rabbitmq/lib/puppet/provider/rabbitmq_policy/rabbitmqctl.rb @@ -0,0 +1,119 @@ +require 'json' +require 'puppet/util/package' + +require File.expand_path(File.join(File.dirname(__FILE__), '..', 'rabbitmqctl')) +Puppet::Type.type(:rabbitmq_policy).provide(:rabbitmqctl, :parent => Puppet::Provider::Rabbitmqctl) do + + defaultfor :feature => :posix + + # cache policies + def self.policies(name, vhost) + @policies = {} unless @policies + unless @policies[vhost] + @policies[vhost] = {} + self.run_with_retries { + rabbitmqctl('list_policies', '-q', '-p', vhost) + }.split(/\n/).each do |line| + # rabbitmq<3.2 does not support the applyto field + # 1 2 3? 4 5 6 + # / ha-all all .* {"ha-mode":"all","ha-sync-mode":"automatic"} 0 + if line =~ /^(\S+)\s+(\S+)\s+(all|exchanges|queues)?\s*(\S+)\s+(\S+)\s+(\d+)$/ + applyto = $3 || 'all' + @policies[vhost][$2] = { + :applyto => applyto, + :pattern => $4, + :definition => JSON.parse($5), + :priority => $6} + else + raise Puppet::Error, "cannot parse line from list_policies:#{line}" + end + end + end + @policies[vhost][name] + end + + def policies(name, vhost) + self.class.policies(vhost, name) + end + + def should_policy + @should_policy ||= resource[:name].rpartition('@').first + end + + def should_vhost + @should_vhost ||= resource[:name].rpartition('@').last + end + + def create + set_policy + end + + def destroy + rabbitmqctl('clear_policy', '-p', should_vhost, should_policy) + end + + def exists? + policies(should_vhost, should_policy) + end + + def pattern + policies(should_vhost, should_policy)[:pattern] + end + + def pattern=(pattern) + set_policy + end + + def applyto + policies(should_vhost, should_policy)[:applyto] + end + + def applyto=(applyto) + set_policy + end + + def definition + policies(should_vhost, should_policy)[:definition] + end + + def definition=(definition) + set_policy + end + + def priority + policies(should_vhost, should_policy)[:priority] + end + + def priority=(priority) + set_policy + end + + def set_policy + unless @set_policy + @set_policy = true + resource[:applyto] ||= applyto + resource[:definition] ||= definition + resource[:pattern] ||= pattern + resource[:priority] ||= priority + # rabbitmq>=3.2.0 + if Puppet::Util::Package.versioncmp(self.class.rabbitmq_version, '3.2.0') >= 0 + rabbitmqctl('set_policy', + '-p', should_vhost, + '--priority', resource[:priority], + '--apply-to', resource[:applyto].to_s, + should_policy, + resource[:pattern], + resource[:definition].to_json + ) + else + rabbitmqctl('set_policy', + '-p', should_vhost, + should_policy, + resource[:pattern], + resource[:definition].to_json, + resource[:priority] + ) + end + end + end +end diff --git a/rabbitmq/lib/puppet/provider/rabbitmq_queue/rabbitmqadmin.rb b/rabbitmq/lib/puppet/provider/rabbitmq_queue/rabbitmqadmin.rb new file mode 100644 index 000000000..b0ecb1f5a --- /dev/null +++ b/rabbitmq/lib/puppet/provider/rabbitmq_queue/rabbitmqadmin.rb @@ -0,0 +1,105 @@ +require 'json' +require 'puppet' +Puppet::Type.type(:rabbitmq_queue).provide(:rabbitmqadmin) do + + if Puppet::PUPPETVERSION.to_f < 3 + commands :rabbitmqctl => 'rabbitmqctl' + commands :rabbitmqadmin => '/usr/local/bin/rabbitmqadmin' + else + has_command(:rabbitmqctl, 'rabbitmqctl') do + environment :HOME => "/tmp" + end + has_command(:rabbitmqadmin, '/usr/local/bin/rabbitmqadmin') do + environment :HOME => "/tmp" + end + end + defaultfor :feature => :posix + + def should_vhost + if @should_vhost + @should_vhost + else + @should_vhost = resource[:name].rpartition('@').last + end + end + + def self.all_vhosts + vhosts = [] + rabbitmqctl('list_vhosts', '-q').split(/\n/).collect do |vhost| + vhosts.push(vhost) + end + vhosts + end + + def self.all_queues(vhost) + rabbitmqctl('list_queues', '-q', '-p', vhost, 'name', 'durable', 'auto_delete', 'arguments').split(/\n/) + end + + def self.instances + resources = [] + all_vhosts.each do |vhost| + all_queues(vhost).collect do |line| + name, durable, auto_delete, arguments = line.split() + # Convert output of arguments from the rabbitmqctl command to a json string. + if !arguments.nil? + arguments = arguments.gsub(/^\[(.*)\]$/, "").gsub(/\{("(?:.|\\")*?"),/, '{\1:').gsub(/\},\{/, ",") + if arguments == "" + arguments = '{}' + end + else + arguments = '{}' + end + queue = { + :durable => durable, + :auto_delete => auto_delete, + :arguments => JSON.parse(arguments), + :ensure => :present, + :name => "%s@%s" % [name, vhost], + } + resources << new(queue) if queue[:name] + end + end + resources + end + + def self.prefetch(resources) + packages = instances + resources.keys.each do |name| + if provider = packages.find{ |pkg| pkg.name == name } + resources[name].provider = provider + end + end + end + + def exists? + @property_hash[:ensure] == :present + end + + def create + vhost_opt = should_vhost ? "--vhost=#{should_vhost}" : '' + name = resource[:name].rpartition('@').first + arguments = resource[:arguments] + if arguments.nil? + arguments = {} + end + rabbitmqadmin('declare', + 'queue', + vhost_opt, + "--user=#{resource[:user]}", + "--password=#{resource[:password]}", + "name=#{name}", + "durable=#{resource[:durable]}", + "auto_delete=#{resource[:auto_delete]}", + "arguments=#{arguments.to_json}" + ) + @property_hash[:ensure] = :present + end + + def destroy + vhost_opt = should_vhost ? "--vhost=#{should_vhost}" : '' + name = resource[:name].rpartition('@').first + rabbitmqadmin('delete', 'queue', vhost_opt, "--user=#{resource[:user]}", "--password=#{resource[:password]}", "name=#{name}") + @property_hash[:ensure] = :absent + end + +end diff --git a/rabbitmq/lib/puppet/provider/rabbitmq_user/rabbitmqctl.rb b/rabbitmq/lib/puppet/provider/rabbitmq_user/rabbitmqctl.rb index ef284bdcd..9cedd2aa6 100644 --- a/rabbitmq/lib/puppet/provider/rabbitmq_user/rabbitmqctl.rb +++ b/rabbitmq/lib/puppet/provider/rabbitmq_user/rabbitmqctl.rb @@ -1,6 +1,7 @@ require 'puppet' require 'set' -Puppet::Type.type(:rabbitmq_user).provide(:rabbitmqctl) do +require File.expand_path(File.join(File.dirname(__FILE__), '..', 'rabbitmqctl')) +Puppet::Type.type(:rabbitmq_user).provide(:rabbitmqctl, :parent => Puppet::Provider::Rabbitmqctl) do if Puppet::PUPPETVERSION.to_f < 3 commands :rabbitmqctl => 'rabbitmqctl' @@ -13,7 +14,9 @@ defaultfor :feature => :posix def self.instances - rabbitmqctl('list_users').split(/\n/)[1..-2].collect do |line| + self.run_with_retries { + rabbitmqctl('-q', 'list_users') + }.split(/\n/).collect do |line| if line =~ /^(\S+)(\s+\[.*?\]|)$/ new(:name => $1) else @@ -32,17 +35,37 @@ def create end end + def change_password + rabbitmqctl('change_password', resource[:name], resource[:password]) + end + + def password + nil + end + + + def check_password + response = rabbitmqctl('eval', 'rabbit_auth_backend_internal:check_user_login(<<"' + resource[:name] + '">>, [{password, <<"' + resource[:password] +'">>}]).') + if response.include? 'invalid credentials' + false + else + true + end + end + def destroy rabbitmqctl('delete_user', resource[:name]) end def exists? - rabbitmqctl('list_users').split(/\n/)[1..-2].detect do |line| + self.class.run_with_retries { + rabbitmqctl('-q', 'list_users') + }.split(/\n/).detect do |line| line.match(/^#{Regexp.escape(resource[:name])}(\s+(\[.*?\]|\S+)|)$/) end end - + def tags get_user_tags.entries.sort end @@ -90,9 +113,9 @@ def make_user_admin private def get_user_tags - match = rabbitmqctl('list_users').split(/\n/)[1..-2].collect do |line| + match = rabbitmqctl('-q', 'list_users').split(/\n/).collect do |line| line.match(/^#{Regexp.escape(resource[:name])}\s+\[(.*?)\]/) end.compact.first - Set.new(match[1].split(/, /)) if match + Set.new(match[1].split(' ').map{|x| x.gsub(/,$/, '')}) if match end end diff --git a/rabbitmq/lib/puppet/provider/rabbitmq_user_permissions/rabbitmqctl.rb b/rabbitmq/lib/puppet/provider/rabbitmq_user_permissions/rabbitmqctl.rb index 83bd808e2..a0b8b5a1a 100644 --- a/rabbitmq/lib/puppet/provider/rabbitmq_user_permissions/rabbitmqctl.rb +++ b/rabbitmq/lib/puppet/provider/rabbitmq_user_permissions/rabbitmqctl.rb @@ -1,4 +1,5 @@ -Puppet::Type.type(:rabbitmq_user_permissions).provide(:rabbitmqctl) do +require File.expand_path(File.join(File.dirname(__FILE__), '..', 'rabbitmqctl')) +Puppet::Type.type(:rabbitmq_user_permissions).provide(:rabbitmqctl, :parent => Puppet::Provider::Rabbitmqctl) do if Puppet::PUPPETVERSION.to_f < 3 commands :rabbitmqctl => 'rabbitmqctl' @@ -15,7 +16,10 @@ def self.users(name, vhost) @users = {} unless @users unless @users[name] @users[name] = {} - rabbitmqctl('list_user_permissions', name).split(/\n/)[1..-2].each do |line| + self.run_with_retries { + rabbitmqctl('-q', 'list_user_permissions', name) + }.split(/\n/).each do |line| + line = self::strip_backslashes(line) if line =~ /^(\S+)\s+(\S*)\s+(\S*)\s+(\S*)$/ @users[name][$1] = {:configure => $2, :read => $4, :write => $3} @@ -51,7 +55,7 @@ def create resource[:configure_permission] ||= "''" resource[:read_permission] ||= "''" resource[:write_permission] ||= "''" - rabbitmqctl('set_permissions', '-p', should_vhost, should_user, resource[:configure_permission], resource[:write_permission], resource[:read_permission]) + rabbitmqctl('set_permissions', '-p', should_vhost, should_user, resource[:configure_permission], resource[:write_permission], resource[:read_permission]) end def destroy @@ -102,4 +106,9 @@ def set_permissions end end + def self.strip_backslashes(string) + # See: https://github.com/rabbitmq/rabbitmq-server/blob/v1_7/docs/rabbitmqctl.1.pod#output-escaping + string.gsub(/\\\\/, '\\') + end + end diff --git a/rabbitmq/lib/puppet/provider/rabbitmq_vhost/rabbitmqctl.rb b/rabbitmq/lib/puppet/provider/rabbitmq_vhost/rabbitmqctl.rb index 2ee45c311..fbd389d87 100644 --- a/rabbitmq/lib/puppet/provider/rabbitmq_vhost/rabbitmqctl.rb +++ b/rabbitmq/lib/puppet/provider/rabbitmq_vhost/rabbitmqctl.rb @@ -1,4 +1,5 @@ -Puppet::Type.type(:rabbitmq_vhost).provide(:rabbitmqctl) do +require File.expand_path(File.join(File.dirname(__FILE__), '..', 'rabbitmqctl')) +Puppet::Type.type(:rabbitmq_vhost).provide(:rabbitmqctl, :parent => Puppet::Provider::Rabbitmqctl) do if Puppet::PUPPETVERSION.to_f < 3 commands :rabbitmqctl => 'rabbitmqctl' @@ -9,7 +10,9 @@ end def self.instances - rabbitmqctl('list_vhosts').split(/\n/)[1..-2].map do |line| + self.run_with_retries { + rabbitmqctl('-q', 'list_vhosts') + }.split(/\n/).map do |line| if line =~ /^(\S+)$/ new(:name => $1) else @@ -27,7 +30,9 @@ def destroy end def exists? - out = rabbitmqctl('list_vhosts').split(/\n/)[1..-2].detect do |line| + out = self.class.run_with_retries { + rabbitmqctl('-q', 'list_vhosts') + }.split(/\n/).detect do |line| line.match(/^#{Regexp.escape(resource[:name])}$/) end end diff --git a/rabbitmq/lib/puppet/provider/rabbitmqctl.rb b/rabbitmq/lib/puppet/provider/rabbitmqctl.rb new file mode 100644 index 000000000..d23664569 --- /dev/null +++ b/rabbitmq/lib/puppet/provider/rabbitmqctl.rb @@ -0,0 +1,33 @@ +class Puppet::Provider::Rabbitmqctl < Puppet::Provider + initvars + commands :rabbitmqctl => 'rabbitmqctl' + + def self.rabbitmq_version + output = rabbitmqctl('-q', 'status') + version = output.match(/\{rabbit,"RabbitMQ","([\d\.]+)"\}/) + version[1] if version + end + + # Retry the given code block 'count' retries or until the + # command suceeeds. Use 'step' delay between retries. + # Limit each query time by 'timeout'. + # For example: + # users = self.class.run_with_retries { rabbitmqctl 'list_users' } + def self.run_with_retries(count=30, step=6, timeout=10) + count.times do |n| + begin + output = Timeout::timeout(timeout) do + yield + end + rescue Puppet::ExecutionFailure, Timeout + Puppet.debug 'Command failed, retrying' + sleep step + else + Puppet.debug 'Command succeeded' + return output + end + end + raise Puppet::Error, "Command is still failing after #{count * step} seconds expired!" + end + +end diff --git a/rabbitmq/lib/puppet/type/rabbitmq_binding.rb b/rabbitmq/lib/puppet/type/rabbitmq_binding.rb new file mode 100644 index 000000000..130948003 --- /dev/null +++ b/rabbitmq/lib/puppet/type/rabbitmq_binding.rb @@ -0,0 +1,96 @@ +Puppet::Type.newtype(:rabbitmq_binding) do + desc 'Native type for managing rabbitmq bindings' + + ensurable do + defaultto(:present) + newvalue(:present) do + provider.create + end + newvalue(:absent) do + provider.destroy + end + end + + newparam(:name, :namevar => true) do + desc 'source and destination of bind' + newvalues(/^\S*@\S+@\S+$/) + end + + newparam(:destination_type) do + desc 'binding destination_type' + newvalues(/queue|exchange/) + defaultto('queue') + end + + newparam(:routing_key) do + desc 'binding routing_key' + newvalues(/^\S*$/) + end + + newparam(:arguments) do + desc 'binding arguments' + defaultto {} + validate do |value| + resource.validate_argument(value) + end + end + + newparam(:user) do + desc 'The user to use to connect to rabbitmq' + defaultto('guest') + newvalues(/^\S+$/) + end + + newparam(:password) do + desc 'The password to use to connect to rabbitmq' + defaultto('guest') + newvalues(/\S+/) + end + + autorequire(:rabbitmq_vhost) do + [self[:name].split('@')[2]] + end + + autorequire(:rabbitmq_exchange) do + setup_autorequire('exchange') + end + + autorequire(:rabbitmq_queue) do + setup_autorequire('queue') + end + + autorequire(:rabbitmq_user) do + [self[:user]] + end + + autorequire(:rabbitmq_user_permissions) do + [ + "#{self[:user]}@#{self[:name].split('@')[1]}", + "#{self[:user]}@#{self[:name].split('@')[0]}" + ] + end + + def setup_autorequire(type) + destination_type = value(:destination_type) + if type == 'exchange' + rval = ["#{self[:name].split('@')[0]}@#{self[:name].split('@')[2]}"] + if destination_type == type + rval.push("#{self[:name].split('@')[1]}@#{self[:name].split('@')[2]}") + end + else + if destination_type == type + rval = ["#{self[:name].split('@')[1]}@#{self[:name].split('@')[2]}"] + else + rval = [] + end + end + rval + end + + def validate_argument(argument) + unless [Hash].include?(argument.class) + raise ArgumentError, "Invalid argument" + end + end + +end diff --git a/rabbitmq/lib/puppet/type/rabbitmq_erlang_cookie.rb b/rabbitmq/lib/puppet/type/rabbitmq_erlang_cookie.rb new file mode 100644 index 000000000..564af5253 --- /dev/null +++ b/rabbitmq/lib/puppet/type/rabbitmq_erlang_cookie.rb @@ -0,0 +1,22 @@ +Puppet::Type.newtype(:rabbitmq_erlang_cookie) do + desc 'Type to manage the rabbitmq erlang cookie securely' + + newparam(:path, :namevar => true) + + newproperty(:content) do + desc 'Content of cookie' + newvalues(/^\S+$/) + def change_to_s(current, desired) + "The rabbitmq erlang cookie was changed" + end + end + + newparam(:force) do + defaultto(:false) + newvalues(:true, :false) + end + + newparam(:service_name) do + newvalues(/^\S+$/) + end +end diff --git a/rabbitmq/lib/puppet/type/rabbitmq_policy.rb b/rabbitmq/lib/puppet/type/rabbitmq_policy.rb new file mode 100644 index 000000000..c147c8039 --- /dev/null +++ b/rabbitmq/lib/puppet/type/rabbitmq_policy.rb @@ -0,0 +1,76 @@ +Puppet::Type.newtype(:rabbitmq_policy) do + desc 'Type for managing rabbitmq policies' + + ensurable do + defaultto(:present) + newvalue(:present) do + provider.create + end + newvalue(:absent) do + provider.destroy + end + end + + autorequire(:service) { 'rabbitmq-server' } + + validate do + fail('pattern parameter is required.') if self[:ensure] == :present and self[:pattern].nil? + fail('definition parameter is required.') if self[:ensure] == :present and self[:definition].nil? + end + + newparam(:name, :namevar => true) do + desc 'combination of policy@vhost to create policy for' + newvalues(/^\S+@\S+$/) + end + + newproperty(:pattern) do + desc 'policy pattern' + validate do |value| + resource.validate_pattern(value) + end + end + + newproperty(:applyto) do + desc 'policy apply to' + newvalue(:all) + newvalue(:exchanges) + newvalue(:queues) + defaultto :all + end + + newproperty(:definition) do + desc 'policy definition' + validate do |value| + resource.validate_definition(value) + end + end + + newproperty(:priority) do + desc 'policy priority' + newvalues(/^\d+$/) + defaultto 0 + end + + autorequire(:rabbitmq_vhost) do + [self[:name].split('@')[1]] + end + + def validate_pattern(value) + begin + Regexp.new(value) + rescue RegexpError + raise ArgumentError, "Invalid regexp #{value}" + end + end + + def validate_definition(definition) + unless [Hash].include?(definition.class) + raise ArgumentError, "Invalid definition" + end + definition.each do |k,v| + unless [String].include?(v.class) + raise ArgumentError, "Invalid definition" + end + end + end +end diff --git a/rabbitmq/lib/puppet/type/rabbitmq_queue.rb b/rabbitmq/lib/puppet/type/rabbitmq_queue.rb new file mode 100644 index 000000000..464a2ca6e --- /dev/null +++ b/rabbitmq/lib/puppet/type/rabbitmq_queue.rb @@ -0,0 +1,68 @@ +Puppet::Type.newtype(:rabbitmq_queue) do + desc 'Native type for managing rabbitmq queue' + + ensurable do + defaultto(:present) + newvalue(:present) do + provider.create + end + newvalue(:absent) do + provider.destroy + end + end + + newparam(:name, :namevar => true) do + desc 'Name of queue' + newvalues(/^\S*@\S+$/) + end + + newparam(:durable) do + desc 'Queue is durable' + newvalues(/true|false/) + defaultto('true') + end + + newparam(:auto_delete) do + desc 'Queue will be auto deleted' + newvalues(/true|false/) + defaultto('false') + end + + newparam(:arguments) do + desc 'Queue arguments example: {x-message-ttl => 60, x-expires => 10}' + defaultto {} + validate do |value| + resource.validate_argument(value) + end + end + + newparam(:user) do + desc 'The user to use to connect to rabbitmq' + defaultto('guest') + newvalues(/^\S+$/) + end + + newparam(:password) do + desc 'The password to use to connect to rabbitmq' + defaultto('guest') + newvalues(/\S+/) + end + + autorequire(:rabbitmq_vhost) do + [self[:name].split('@')[1]] + end + + autorequire(:rabbitmq_user) do + [self[:user]] + end + + autorequire(:rabbitmq_user_permissions) do + ["#{self[:user]}@#{self[:name].split('@')[1]}"] + end + + def validate_argument(argument) + unless [Hash].include?(argument.class) + raise ArgumentError, "Invalid argument" + end + end +end diff --git a/rabbitmq/lib/puppet/type/rabbitmq_user.rb b/rabbitmq/lib/puppet/type/rabbitmq_user.rb index be5219d5c..66eef92c2 100644 --- a/rabbitmq/lib/puppet/type/rabbitmq_user.rb +++ b/rabbitmq/lib/puppet/type/rabbitmq_user.rb @@ -18,9 +18,17 @@ newvalues(/^\S+$/) end - # newproperty(:password) do - newparam(:password) do - desc 'User password to be set *on creation*' + newproperty(:password) do + desc 'User password to be set *on creation* and validated each run' + def insync?(is) + provider.check_password + end + def set(value) + provider.change_password + end + def change_to_s(current, desired) + "password has been changed" + end end newproperty(:admin) do diff --git a/rabbitmq/manifests/config.pp b/rabbitmq/manifests/config.pp index 2795cd073..c111dab5b 100644 --- a/rabbitmq/manifests/config.pp +++ b/rabbitmq/manifests/config.pp @@ -1,7 +1,9 @@ +# Class: rabbitmq::config +# Sets all the configuration values for RabbitMQ and creates the directories for +# config and ssl. class rabbitmq::config { $admin_enable = $rabbitmq::admin_enable - $cluster_disk_nodes = $rabbitmq::cluster_disk_nodes $cluster_node_type = $rabbitmq::cluster_node_type $cluster_nodes = $rabbitmq::cluster_nodes $config = $rabbitmq::config @@ -29,42 +31,38 @@ $ssl_stomp_port = $rabbitmq::ssl_stomp_port $ssl_verify = $rabbitmq::ssl_verify $ssl_fail_if_no_peer_cert = $rabbitmq::ssl_fail_if_no_peer_cert + $ssl_versions = $rabbitmq::ssl_versions $stomp_port = $rabbitmq::stomp_port + $ldap_auth = $rabbitmq::ldap_auth + $ldap_server = $rabbitmq::ldap_server + $ldap_user_dn_pattern = $rabbitmq::ldap_user_dn_pattern + $ldap_use_ssl = $rabbitmq::ldap_use_ssl + $ldap_port = $rabbitmq::ldap_port + $ldap_log = $rabbitmq::ldap_log $wipe_db_on_cookie_change = $rabbitmq::wipe_db_on_cookie_change $config_variables = $rabbitmq::config_variables $config_kernel_variables = $rabbitmq::config_kernel_variables $cluster_partition_handling = $rabbitmq::cluster_partition_handling $default_env_variables = { - 'RABBITMQ_NODE_PORT' => $port, - 'RABBITMQ_NODE_IP_ADDRESS' => $node_ip_address + 'NODE_PORT' => $port, + 'NODE_IP_ADDRESS' => $node_ip_address } # Handle env variables. $environment_variables = merge($default_env_variables, $rabbitmq::environment_variables) - # Handle deprecated option. - if $cluster_disk_nodes != [] { - notify { 'cluster_disk_nodes': - message => 'WARNING: The cluster_disk_nodes is deprecated. - Use cluster_nodes instead.', - } - $r_cluster_nodes = $cluster_disk_nodes - } else { - $r_cluster_nodes = $cluster_nodes - } - file { '/etc/rabbitmq': - ensure => directory, - owner => '0', - group => '0', - mode => '0644', + ensure => directory, + owner => '0', + group => '0', + mode => '0644', } file { '/etc/rabbitmq/ssl': - ensure => directory, - owner => '0', - group => '0', - mode => '0644', + ensure => directory, + owner => '0', + group => '0', + mode => '0644', } file { 'rabbitmq.config': @@ -87,37 +85,29 @@ notify => Class['rabbitmq::service'], } + file { 'rabbitmqadmin.conf': + ensure => file, + path => '/etc/rabbitmq/rabbitmqadmin.conf', + content => template('rabbitmq/rabbitmqadmin.conf.erb'), + owner => '0', + group => '0', + mode => '0644', + require => File['/etc/rabbitmq'], + } if $config_cluster { - file { 'erlang_cookie': - ensure => 'present', - path => '/var/lib/rabbitmq/.erlang.cookie', - owner => 'rabbitmq', - group => 'rabbitmq', - mode => '0400', - content => $erlang_cookie, - replace => true, - before => File['rabbitmq.config'], - notify => Class['rabbitmq::service'], - } - - # rabbitmq_erlang_cookie is a fact in this module. - if $erlang_cookie != $::rabbitmq_erlang_cookie { - # Safety check. - if $wipe_db_on_cookie_change { - exec { 'wipe_db': - command => "puppet resource service ${service_name} ensure=stopped; rm -rf /var/lib/rabbitmq/mnesia", - path => '/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin', - } - File['erlang_cookie'] { - require => Exec['wipe_db'], - } - } else { - fail("ERROR: The current erlang cookie is ${::rabbitmq_erlang_cookie} and needs to change to ${erlang_cookie}. In order to do this the RabbitMQ database needs to be wiped. Please set the parameter called wipe_db_on_cookie_change to true to allow this to happen automatically.") + if $erlang_cookie == undef { + fail('You must set the $erlang_cookie value in order to configure clustering.') + } else { + rabbitmq_erlang_cookie { '/var/lib/rabbitmq/.erlang.cookie': + content => $erlang_cookie, + force => $wipe_db_on_cookie_change, + service_name => $service_name, + before => File['rabbitmq.config'], + notify => Class['rabbitmq::service'], } } - } diff --git a/rabbitmq/manifests/init.pp b/rabbitmq/manifests/init.pp index aa42b8127..1ac3f6d61 100644 --- a/rabbitmq/manifests/init.pp +++ b/rabbitmq/manifests/init.pp @@ -1,7 +1,6 @@ - # +# Main rabbitmq class class rabbitmq( $admin_enable = $rabbitmq::params::admin_enable, - $cluster_disk_nodes = $rabbitmq::params::cluster_disk_nodes, $cluster_node_type = $rabbitmq::params::cluster_node_type, $cluster_nodes = $rabbitmq::params::cluster_nodes, $config = $rabbitmq::params::config, @@ -21,7 +20,8 @@ $package_gpg_key = $rabbitmq::params::package_gpg_key, $package_name = $rabbitmq::params::package_name, $package_provider = $rabbitmq::params::package_provider, - $package_source = $rabbitmq::params::package_source, + $package_source = undef, + $repos_ensure = $rabbitmq::params::repos_ensure, $manage_repos = $rabbitmq::params::manage_repos, $plugin_dir = $rabbitmq::params::plugin_dir, $port = $rabbitmq::params::port, @@ -39,6 +39,7 @@ $ssl_stomp_port = $rabbitmq::params::ssl_stomp_port, $ssl_verify = $rabbitmq::params::ssl_verify, $ssl_fail_if_no_peer_cert = $rabbitmq::params::ssl_fail_if_no_peer_cert, + $ssl_versions = $rabbitmq::params::ssl_versions, $stomp_ensure = $rabbitmq::params::stomp_ensure, $ldap_auth = $rabbitmq::params::ldap_auth, $ldap_server = $rabbitmq::params::ldap_server, @@ -63,11 +64,10 @@ validate_string($package_gpg_key) validate_string($package_name) validate_string($package_provider) - validate_bool($manage_repos) + validate_bool($repos_ensure) validate_re($version, '^\d+\.\d+\.\d+(-\d+)*$') # Allow 3 digits and optional -n postfix. # Validate config parameters. - validate_array($cluster_disk_nodes) - validate_re($cluster_node_type, '^(ram|disc)$') + validate_re($cluster_node_type, '^(ram|disc|disk)$') # Both disc and disk are valid http://www.rabbitmq.com/clustering.html validate_array($cluster_nodes) validate_string($config) validate_absolute_path($config_path) @@ -118,12 +118,44 @@ warning('$ssl_stomp_port requires that $ssl => true and will be ignored') } + if $ssl_versions { + if $ssl { + validate_array($ssl_versions) + } else { + fail('$ssl_versions requires that $ssl => true') + } + } + + # This needs to happen here instead of params.pp because + # $package_source needs to override the constructed value in params.pp + if $package_source { # $package_source was specified by user so use that one + $real_package_source = $package_source + # NOTE(bogdando) do not enforce the source value for yum provider #MODULES-1631 + } elsif $package_provider != 'yum' { + # package_source was not specified, so construct it, unless the provider is 'yum' + case $::osfamily { + 'RedHat', 'SUSE': { + $base_version = regsubst($version,'^(.*)-\d$','\1') + $real_package_source = "http://www.rabbitmq.com/releases/rabbitmq-server/v${base_version}/rabbitmq-server-${version}.noarch.rpm" + } + default: { # Archlinux and Debian + $real_package_source = '' + } + } + } else { # for yum provider, use the source as is + $real_package_source = $package_source + } + include '::rabbitmq::install' include '::rabbitmq::config' include '::rabbitmq::service' include '::rabbitmq::management' - if $rabbitmq::manage_repos == true { + if $manage_repos != undef { + warning('$manage_repos is now deprecated. Please use $repos_ensure instead') + } + + if $manage_repos != false { case $::osfamily { 'RedHat', 'SUSE': { include '::rabbitmq::repo::rhel' } @@ -142,9 +174,9 @@ include '::rabbitmq::install::rabbitmqadmin' rabbitmq_plugin { 'rabbitmq_management': - ensure => present, - require => Class['rabbitmq::install'], - notify => Class['rabbitmq::service'], + ensure => present, + require => Class['rabbitmq::install'], + notify => Class['rabbitmq::service'], provider => 'rabbitmqplugins' } @@ -153,9 +185,9 @@ if $stomp_ensure { rabbitmq_plugin { 'rabbitmq_stomp': - ensure => present, - require => Class['rabbitmq::install'], - notify => Class['rabbitmq::service'], + ensure => present, + require => Class['rabbitmq::install'], + notify => Class['rabbitmq::service'], provider => 'rabbitmqplugins' } } @@ -169,9 +201,6 @@ } } - # Anchor this as per #8040 - this ensures that classes won't float off and - # mess everything up. You can read about this at: - # http://docs.puppetlabs.com/puppet/2.7/reference/lang_containment.html#known-issues anchor { 'rabbitmq::begin': } anchor { 'rabbitmq::end': } diff --git a/rabbitmq/manifests/install.pp b/rabbitmq/manifests/install.pp index 09fe3b321..f2df83aa0 100644 --- a/rabbitmq/manifests/install.pp +++ b/rabbitmq/manifests/install.pp @@ -1,9 +1,11 @@ +# Class rabbitmq::install +# Ensures the rabbitmq-server exists class rabbitmq::install { $package_ensure = $rabbitmq::package_ensure $package_name = $rabbitmq::package_name $package_provider = $rabbitmq::package_provider - $package_source = $rabbitmq::package_source + $package_source = $rabbitmq::real_package_source package { 'rabbitmq-server': ensure => $package_ensure, diff --git a/rabbitmq/manifests/install/rabbitmqadmin.pp b/rabbitmq/manifests/install/rabbitmqadmin.pp index 184a5258d..5b9f527b9 100644 --- a/rabbitmq/manifests/install/rabbitmqadmin.pp +++ b/rabbitmq/manifests/install/rabbitmqadmin.pp @@ -1,15 +1,24 @@ # class rabbitmq::install::rabbitmqadmin { - $management_port = $rabbitmq::management_port + if($rabbitmq::ssl) { + $management_port = $rabbitmq::ssl_management_port + } + else { + $management_port = $rabbitmq::management_port + } + $default_user = $rabbitmq::default_user $default_pass = $rabbitmq::default_pass $protocol = $rabbitmq::ssl ? { false => 'http', default => 'https' } staging::file { 'rabbitmqadmin': - target => '/var/lib/rabbitmq/rabbitmqadmin', - source => "${protocol}://${default_user}:${default_pass}@localhost:${management_port}/cli/rabbitmqadmin", - require => [ + target => '/var/lib/rabbitmq/rabbitmqadmin', + source => "${protocol}://${default_user}:${default_pass}@localhost:${management_port}/cli/rabbitmqadmin", + curl_option => '-k --noproxy localhost --retry 30 --retry-delay 6', + timeout => '180', + wget_option => '--no-proxy', + require => [ Class['rabbitmq::service'], Rabbitmq_plugin['rabbitmq_management'] ], diff --git a/rabbitmq/manifests/params.pp b/rabbitmq/manifests/params.pp index abe7c52b7..4e4ba3221 100644 --- a/rabbitmq/manifests/params.pp +++ b/rabbitmq/manifests/params.pp @@ -9,28 +9,21 @@ $package_ensure = 'installed' $package_name = 'rabbitmq' $service_name = 'rabbitmq' - $package_source = '' $version = '3.1.3-1' - $base_version = regsubst($version,'^(.*)-\d$','\1') - # This must remain at the end as we need $base_version and $version defined first } 'Debian': { $package_ensure = 'installed' $package_name = 'rabbitmq-server' $service_name = 'rabbitmq-server' $package_provider = 'apt' - $package_source = '' $version = '3.1.5' } 'RedHat': { $package_ensure = 'installed' $package_name = 'rabbitmq-server' $service_name = 'rabbitmq-server' - $package_provider = 'yum' + $package_provider = 'rpm' $version = '3.1.5-1' - $base_version = regsubst($version,'^(.*)-\d$','\1') - # This must remain at the end as we need $base_version and $version defined first. - $package_source = "http://www.rabbitmq.com/releases/rabbitmq-server/v${base_version}/rabbitmq-server-${version}.noarch.rpm" } 'SUSE': { $package_ensure = 'installed' @@ -38,9 +31,6 @@ $service_name = 'rabbitmq-server' $package_provider = 'zypper' $version = '3.1.5-1' - $base_version = regsubst($version,'^(.*)-\d$','\1') - # This must remain at the end as we need $base_version and $version defined first. - $package_source = "http://www.rabbitmq.com/releases/rabbitmq-server/v${base_version}/rabbitmq-server-${version}.noarch.rpm" } default: { fail("The ${module_name} module is not supported on an ${::osfamily} based system.") @@ -52,11 +42,11 @@ $management_port = '15672' $package_apt_pin = '' $package_gpg_key = 'http://www.rabbitmq.com/rabbitmq-signing-key-public.asc' - $manage_repos = true + $repos_ensure = true + $manage_repos = undef $service_ensure = 'running' $service_manage = true #config - $cluster_disk_nodes = [] $cluster_node_type = 'disc' $cluster_nodes = [] $config = 'rabbitmq/rabbitmq.config.erb' @@ -68,7 +58,7 @@ $delete_guest_user = false $env_config = 'rabbitmq/rabbitmq-env.conf.erb' $env_config_path = '/etc/rabbitmq/rabbitmq-env.conf' - $erlang_cookie = 'EOKOWXQREETZSHFNTPEY' + $erlang_cookie = undef $node_ip_address = 'UNSET' $plugin_dir = "/usr/lib/rabbitmq/lib/rabbitmq_server-${version}/plugins" $port = '5672' @@ -82,11 +72,12 @@ $ssl_management_port = '15671' $ssl_stomp_port = '6164' $ssl_verify = 'verify_none' - $ssl_fail_if_no_peer_cert = 'false' + $ssl_fail_if_no_peer_cert = false + $ssl_versions = undef $stomp_ensure = false $ldap_auth = false $ldap_server = 'ldap' - $ldap_user_dn_pattern = 'cn=${username},ou=People,dc=example,dc=com' + $ldap_user_dn_pattern = 'cn=username,ou=People,dc=example,dc=com' $ldap_use_ssl = false $ldap_port = '389' $ldap_log = false diff --git a/rabbitmq/manifests/repo/apt.pp b/rabbitmq/manifests/repo/apt.pp index 56d08af8a..707c619dc 100644 --- a/rabbitmq/manifests/repo/apt.pp +++ b/rabbitmq/manifests/repo/apt.pp @@ -6,7 +6,7 @@ $release = 'testing', $repos = 'main', $include_src = false, - $key = '056E8E56', + $key = 'F7B8CEA6056E8E56', $key_source = 'http://www.rabbitmq.com/rabbitmq-signing-key-public.asc', $key_content = undef, ) { @@ -15,7 +15,13 @@ Class['rabbitmq::repo::apt'] -> Package<| title == 'rabbitmq-server' |> + $ensure_source = $rabbitmq::repos_ensure ? { + false => 'absent', + default => 'present', + } + apt::source { 'rabbitmq': + ensure => $ensure_source, location => $location, release => $release, repos => $repos, @@ -25,7 +31,7 @@ key_content => $key_content, } - if $pin { + if $pin != '' { validate_re($pin, '\d\d\d') apt::pin { 'rabbitmq': packages => 'rabbitmq-server', diff --git a/rabbitmq/manifests/repo/rhel.pp b/rabbitmq/manifests/repo/rhel.pp index f2271cd46..284909945 100644 --- a/rabbitmq/manifests/repo/rhel.pp +++ b/rabbitmq/manifests/repo/rhel.pp @@ -1,12 +1,16 @@ +# Class: rabbitmq::repo::rhel +# Imports the gpg key if it doesn't already exist. class rabbitmq::repo::rhel { - $package_gpg_key = $rabbitmq::package_gpg_key + if $rabbitmq::repos_ensure { - Class['rabbitmq::repo::rhel'] -> Package<| title == 'rabbitmq-server' |> + $package_gpg_key = $rabbitmq::package_gpg_key - exec { "rpm --import ${package_gpg_key}": - path => ['/bin','/usr/bin','/sbin','/usr/sbin'], - onlyif => 'test `rpm -qa | grep gpg-pubkey-056e8e56-468e43f2 | wc -l` -eq 0', - } + Class['rabbitmq::repo::rhel'] -> Package<| title == 'rabbitmq-server' |> + exec { "rpm --import ${package_gpg_key}": + path => ['/bin','/usr/bin','/sbin','/usr/sbin'], + unless => 'rpm -q gpg-pubkey-056e8e56-468e43f2 2>/dev/null', + } + } } diff --git a/rabbitmq/manifests/server.pp b/rabbitmq/manifests/server.pp index 495ea2f2d..05de184fc 100644 --- a/rabbitmq/manifests/server.pp +++ b/rabbitmq/manifests/server.pp @@ -14,10 +14,8 @@ # [*config*] - contents of config file # [*env_config*] - contents of env-config file # [*config_cluster*] - whether to configure a RabbitMQ cluster -# [*config_mirrored_queues*] - DEPRECATED (doesn't do anything) -# [*cluster_disk_nodes*] - DEPRECATED (use cluster_nodes instead) # [*cluster_nodes*] - which nodes to cluster with (including the current one) -# [*cluster_node_type*] - Type of cluster node (disc or ram) +# [*cluster_node_type*] - Type of cluster node (disc/disk or ram) # [*erlang_cookie*] - erlang cookie, must be the same for all nodes in a cluster # [*wipe_db_on_cookie_change*] - whether to wipe the RabbitMQ data if the specified # erlang_cookie differs from the current one. This is a sad parameter: actually, @@ -45,7 +43,6 @@ $config_stomp = $rabbitmq::params::config_stomp, $stomp_port = $rabbitmq::params::stomp_port, $config_cluster = $rabbitmq::params::config_cluster, - $cluster_disk_nodes = $rabbitmq::params::cluster_disk_nodes, $cluster_nodes = $rabbitmq::params::cluster_nodes, $cluster_node_type = $rabbitmq::params::cluster_node_type, $node_ip_address = $rabbitmq::params::node_ip_address, @@ -53,22 +50,8 @@ $env_config = $rabbitmq::params::env_config, $erlang_cookie = $rabbitmq::params::erlang_cookie, $wipe_db_on_cookie_change = $rabbitmq::params::wipe_db_on_cookie_change, - # DEPRECATED - $manage_service = undef, - $config_mirrored_queues = undef, ) inherits rabbitmq::params { - if $manage_service != undef { - warning('The $manage_service parameter is deprecated; please use $service_manage instead') - $_service_manage = $manage_service - } else { - $_service_manage = $service_manage - } - - if $config_mirrored_queues != undef { - warning('The $config_mirrored_queues parameter is deprecated; it does not affect anything') - } - anchor {'before::rabbimq::class': before => Class['rabbitmq'], } @@ -78,23 +61,22 @@ } class { 'rabbitmq': - port => $port, - delete_guest_user => $delete_guest_user, - package_name => $package_name, - version => $version, - service_name => $service_name, - service_ensure => $service_ensure, - service_manage => $_service_manage, - config_stomp => $config_stomp, - stomp_port => $stomp_port, - config_cluster => $config_cluster, - cluster_disk_nodes => $cluster_disk_nodes, - cluster_nodes => $cluster_nodes, - cluster_node_type => $cluster_node_type, - node_ip_address => $node_ip_address, - config => $config, - env_config => $env_config, - erlang_cookie => $erlang_cookie, - wipe_db_on_cookie_change => $wipe_db_on_cookie_change, + port => $port, + delete_guest_user => $delete_guest_user, + package_name => $package_name, + version => $version, + service_name => $service_name, + service_ensure => $service_ensure, + service_manage => $service_manage, + config_stomp => $config_stomp, + stomp_port => $stomp_port, + config_cluster => $config_cluster, + cluster_nodes => $cluster_nodes, + cluster_node_type => $cluster_node_type, + node_ip_address => $node_ip_address, + config => $config, + env_config => $env_config, + erlang_cookie => $erlang_cookie, + wipe_db_on_cookie_change => $wipe_db_on_cookie_change, } } diff --git a/rabbitmq/metadata.json b/rabbitmq/metadata.json index 3e0f33385..acc819146 100644 --- a/rabbitmq/metadata.json +++ b/rabbitmq/metadata.json @@ -1,24 +1,55 @@ { "name": "puppetlabs-rabbitmq", - "version": "4.1.0", + "version": "5.0.0", "author": "puppetlabs", - "summary": "RabbitMQ Puppet Module", - "license": "Apache 2.0", + "summary": "Installs, configures, and manages RabbitMQ.", + "license": "Apache-2.0", "source": "https://github.com/puppetlabs/puppetlabs-rabbitmq", "project_page": "https://github.com/puppetlabs/puppetlabs-rabbitmq", "issues_url": "https://tickets.puppetlabs.com/browse/MODULES", - "dependencies": [ + "operatingsystem_support": [ + { + "operatingsystem": "RedHat", + "operatingsystemrelease": [ + "5", + "6" + ] + }, + { + "operatingsystem": "CentOS", + "operatingsystemrelease": [ + "5", + "6" + ] + }, { - "name": "puppetlabs/stdlib", - "version_requirement": ">= 2.0.0" + "operatingsystem": "Debian", + "operatingsystemrelease": [ + "6", + "7" + ] }, { - "name": "puppetlabs/apt", - "version_requirement": ">= 1.0.0" + "operatingsystem": "Ubuntu", + "operatingsystemrelease": [ + "12.04", + "14.04" + ] + } + ], + "requirements": [ + { + "name": "pe", + "version_requirement": "3.x" }, { - "name": "nanliu/staging", - "version_requirement": ">= 0.3.1" + "name": "puppet", + "version_requirement": "3.x" } + ], + "dependencies": [ + { "name": "puppetlabs/stdlib", "version_requirement": ">=2.0.0 <5.0.0" }, + { "name": "puppetlabs/apt", "version_requirement": ">=1.0.0 <2.0.0" }, + { "name": "nanliu/staging", "version_requirement": ">=0.3.1 <2.0.0" } ] } diff --git a/rabbitmq/spec/acceptance/class_spec.rb b/rabbitmq/spec/acceptance/class_spec.rb index c0b557673..b5b50cd34 100644 --- a/rabbitmq/spec/acceptance/class_spec.rb +++ b/rabbitmq/spec/acceptance/class_spec.rb @@ -83,7 +83,6 @@ class { 'erlang': epel_enable => true} } EOS - apply_manifest(pp_pre, :catch_failures => true) apply_manifest(pp, :catch_failures => true) end diff --git a/rabbitmq/spec/acceptance/clustering_spec.rb b/rabbitmq/spec/acceptance/clustering_spec.rb index 04627fa6f..438c65ba1 100644 --- a/rabbitmq/spec/acceptance/clustering_spec.rb +++ b/rabbitmq/spec/acceptance/clustering_spec.rb @@ -1,13 +1,38 @@ require 'spec_helper_acceptance' describe 'rabbitmq clustering' do - context 'rabbitmq::config_cluster => true' do + context 'rabbitmq::wipe_db_on_cookie_change => false' do it 'should run successfully' do pp = <<-EOS class { 'rabbitmq': config_cluster => true, cluster_nodes => ['rabbit1', 'rabbit2'], cluster_node_type => 'ram', + erlang_cookie => 'TESTCOOKIE', + wipe_db_on_cookie_change => false, + } + if $::osfamily == 'RedHat' { + class { 'erlang': epel_enable => true} + Class['erlang'] -> Class['rabbitmq'] + } + EOS + + apply_manifest(pp, :expect_failures => true) + end + + describe file('/var/lib/rabbitmq/.erlang.cookie') do + it { should_not contain 'TESTCOOKIE' } + end + + end + context 'rabbitmq::wipe_db_on_cookie_change => true' do + it 'should run successfully' do + pp = <<-EOS + class { 'rabbitmq': + config_cluster => true, + cluster_nodes => ['rabbit1', 'rabbit2'], + cluster_node_type => 'ram', + erlang_cookie => 'TESTCOOKIE', wipe_db_on_cookie_change => true, } if $::osfamily == 'RedHat' { @@ -15,7 +40,7 @@ class { 'erlang': epel_enable => true} Class['erlang'] -> Class['rabbitmq'] } EOS - + apply_manifest(pp, :catch_failures => true) end @@ -29,6 +54,7 @@ class { 'erlang': epel_enable => true} describe file('/var/lib/rabbitmq/.erlang.cookie') do it { should be_file } + it { should contain 'TESTCOOKIE' } end end end diff --git a/rabbitmq/spec/acceptance/nodesets/ubuntu-server-1310-x64.yml b/rabbitmq/spec/acceptance/nodesets/ubuntu-server-1310-x64.yml deleted file mode 100644 index f4b2366f3..000000000 --- a/rabbitmq/spec/acceptance/nodesets/ubuntu-server-1310-x64.yml +++ /dev/null @@ -1,11 +0,0 @@ -HOSTS: - ubuntu-server-1310-x64: - roles: - - master - platform: ubuntu-13.10-amd64 - box : ubuntu-server-1310-x64-vbox4210-nocm - box_url : http://puppet-vagrant-boxes.puppetlabs.com/ubuntu-1310-x64-virtualbox-nocm.box - hypervisor : vagrant -CONFIG: - log_level : debug - type: git diff --git a/rabbitmq/spec/acceptance/policy_spec.rb b/rabbitmq/spec/acceptance/policy_spec.rb new file mode 100644 index 000000000..26858ecc5 --- /dev/null +++ b/rabbitmq/spec/acceptance/policy_spec.rb @@ -0,0 +1,47 @@ +require 'spec_helper_acceptance' + +describe 'rabbitmq policy on a vhost:' do + + + context "create policy resource" do + it 'should run successfully' do + pp = <<-EOS + if $::osfamily == 'RedHat' { + class { 'erlang': epel_enable => true } + Class['erlang'] -> Class['::rabbitmq'] + } + class { '::rabbitmq': + service_manage => true, + port => '5672', + delete_guest_user => true, + admin_enable => true, + } -> + + rabbitmq_vhost { 'myhost': + ensure => present, + } -> + + rabbitmq_policy { 'ha-all@myhost': + pattern => '.*', + priority => 0, + applyto => 'all', + definition => { + 'ha-mode' => 'all', + 'ha-sync-mode' => 'automatic', + }, + } + EOS + + apply_manifest(pp, :catch_failures => true) + apply_manifest(pp, :catch_changes => true) + end + + it 'should have the policy' do + shell('rabbitmqctl list_policies -p myhost') do |r| + expect(r.stdout).to match(/myhost.*ha-all.*ha-sync-mode/) + expect(r.exit_code).to be_zero + end + end + + end +end diff --git a/rabbitmq/spec/acceptance/user_spec.rb b/rabbitmq/spec/acceptance/user_spec.rb new file mode 100644 index 000000000..6aab665a4 --- /dev/null +++ b/rabbitmq/spec/acceptance/user_spec.rb @@ -0,0 +1,38 @@ +require 'spec_helper_acceptance' + +describe 'rabbitmq user:' do + + + context "create user resource" do + it 'should run successfully' do + pp = <<-EOS + if $::osfamily == 'RedHat' { + class { 'erlang': epel_enable => true } + Class['erlang'] -> Class['::rabbitmq'] + } + class { '::rabbitmq': + service_manage => true, + port => '5672', + delete_guest_user => true, + admin_enable => true, + } -> + + rabbitmq_user { 'dan': + admin => true, + password => 'bar', + } + EOS + + apply_manifest(pp, :catch_failures => true) + apply_manifest(pp, :catch_changes => true) + end + + it 'should have the user' do + shell('rabbitmqctl list_users') do |r| + expect(r.stdout).to match(/dan.*administrator/) + expect(r.exit_code).to be_zero + end + end + + end +end diff --git a/rabbitmq/spec/acceptance/vhost_spec.rb b/rabbitmq/spec/acceptance/vhost_spec.rb new file mode 100644 index 000000000..ef1c2a342 --- /dev/null +++ b/rabbitmq/spec/acceptance/vhost_spec.rb @@ -0,0 +1,37 @@ +require 'spec_helper_acceptance' + +describe 'rabbitmq vhost:' do + + + context "create vhost resource" do + it 'should run successfully' do + pp = <<-EOS + if $::osfamily == 'RedHat' { + class { 'erlang': epel_enable => true } + Class['erlang'] -> Class['::rabbitmq'] + } + class { '::rabbitmq': + service_manage => true, + port => '5672', + delete_guest_user => true, + admin_enable => true, + } -> + + rabbitmq_vhost { 'myhost': + ensure => present, + } + EOS + + apply_manifest(pp, :catch_failures => true) + apply_manifest(pp, :catch_changes => true) + end + + it 'should have the vhost' do + shell('rabbitmqctl list_vhosts') do |r| + expect(r.stdout).to match(/myhost/) + expect(r.exit_code).to be_zero + end + end + + end +end diff --git a/rabbitmq/spec/classes/rabbitmq_spec.rb b/rabbitmq/spec/classes/rabbitmq_spec.rb index e82a64e6b..8429c98c4 100644 --- a/rabbitmq/spec/classes/rabbitmq_spec.rb +++ b/rabbitmq/spec/classes/rabbitmq_spec.rb @@ -19,6 +19,7 @@ describe 'apt::source default values' do it 'should add a repo with defaults values' do should contain_apt__source('rabbitmq').with( { + :ensure => 'present', :location => 'http://www.rabbitmq.com/debian/', :release => 'testing', :repos => 'main', @@ -30,8 +31,111 @@ context 'on Debian' do let(:params) {{ :manage_repos => false }} let(:facts) {{ :osfamily => 'Debian', :lsbdistid => 'Debian', :lsbdistcodename => 'squeeze' }} - it 'does not include rabbitmq::repo::apt when manage_repos is false' do - should_not contain_class('rabbitmq::repo::apt') + it 'does ensure rabbitmq apt::source is absent when manage_repos is false' do + should_not contain_apt__source('rabbitmq') + end + end + + context 'on Debian' do + let(:params) {{ :manage_repos => true }} + let(:facts) {{ :osfamily => 'Debian', :lsbdistid => 'Debian', :lsbdistcodename => 'squeeze' }} + + it 'includes rabbitmq::repo::apt' do + should contain_class('rabbitmq::repo::apt') + end + + describe 'apt::source default values' do + it 'should add a repo with defaults values' do + should contain_apt__source('rabbitmq').with( { + :ensure => 'present', + :location => 'http://www.rabbitmq.com/debian/', + :release => 'testing', + :repos => 'main', + }) + end + end + end + + context 'on Debian' do + let(:params) {{ :repos_ensure => false }} + let(:facts) {{ :osfamily => 'Debian', :lsbdistid => 'Debian', :lsbdistcodename => 'squeeze' }} + it 'does ensure rabbitmq apt::source is absent when repos_ensure is false' do + should contain_apt__source('rabbitmq').with( + 'ensure' => 'absent' + ) + end + end + + context 'on Debian' do + let(:params) {{ :repos_ensure => true }} + let(:facts) {{ :osfamily => 'Debian', :lsbdistid => 'Debian', :lsbdistcodename => 'squeeze' }} + + it 'includes rabbitmq::repo::apt' do + should contain_class('rabbitmq::repo::apt') + end + + describe 'apt::source default values' do + it 'should add a repo with defaults values' do + should contain_apt__source('rabbitmq').with( { + :ensure => 'present', + :location => 'http://www.rabbitmq.com/debian/', + :release => 'testing', + :repos => 'main', + }) + end + end + end + + context 'on Debian' do + let(:params) {{ :manage_repos => true, :repos_ensure => false }} + let(:facts) {{ :osfamily => 'Debian', :lsbdistid => 'Debian', :lsbdistcodename => 'squeeze' }} + + it 'includes rabbitmq::repo::apt' do + should contain_class('rabbitmq::repo::apt') + end + + describe 'apt::source default values' do + it 'should add a repo with defaults values' do + should contain_apt__source('rabbitmq').with( { + :ensure => 'absent', + }) + end + end + end + + context 'on Debian' do + let(:params) {{ :manage_repos => true, :repos_ensure => true }} + let(:facts) {{ :osfamily => 'Debian', :lsbdistid => 'Debian', :lsbdistcodename => 'squeeze' }} + + it 'includes rabbitmq::repo::apt' do + should contain_class('rabbitmq::repo::apt') + end + + describe 'apt::source default values' do + it 'should add a repo with defaults values' do + should contain_apt__source('rabbitmq').with( { + :ensure => 'present', + :location => 'http://www.rabbitmq.com/debian/', + :release => 'testing', + :repos => 'main', + }) + end + end + end + + context 'on Debian' do + let(:params) {{ :manage_repos => false, :repos_ensure => true }} + let(:facts) {{ :osfamily => 'Debian', :lsbdistid => 'Debian', :lsbdistcodename => 'squeeze' }} + it 'does ensure rabbitmq apt::source is absent when manage_repos is false and repos_ensure is true' do + should_not contain_apt__source('rabbitmq') + end + end + + context 'on Debian' do + let(:params) {{ :manage_repos => false, :repos_ensure => false }} + let(:facts) {{ :osfamily => 'Debian', :lsbdistid => 'Debian', :lsbdistcodename => 'squeeze' }} + it 'does ensure rabbitmq apt::source is absent when manage_repos is false and repos_ensure is false' do + should_not contain_apt__source('rabbitmq') end end @@ -39,14 +143,79 @@ let(:facts) {{ :osfamily => 'RedHat' }} it 'includes rabbitmq::repo::rhel' do should contain_class('rabbitmq::repo::rhel') + should contain_exec('rpm --import http://www.rabbitmq.com/rabbitmq-signing-key-public.asc') + end + end + + context 'on Redhat' do + let(:params) {{ :repos_ensure => false }} + let(:facts) {{ :osfamily => 'RedHat' }} + it 'does not import repo public key when repos_ensure is false' do + should contain_class('rabbitmq::repo::rhel') + should_not contain_exec('rpm --import http://www.rabbitmq.com/rabbitmq-signing-key-public.asc') + end + end + + context 'on Redhat' do + let(:params) {{ :repos_ensure => true }} + let(:facts) {{ :osfamily => 'RedHat' }} + it 'does import repo public key when repos_ensure is true' do + should contain_class('rabbitmq::repo::rhel') + should contain_exec('rpm --import http://www.rabbitmq.com/rabbitmq-signing-key-public.asc') end end context 'on Redhat' do let(:params) {{ :manage_repos => false }} let(:facts) {{ :osfamily => 'RedHat' }} - it 'does not include rabbitmq::repo::rhel when manage_repos is false' do + it 'does not import repo public key when manage_repos is false' do should_not contain_class('rabbitmq::repo::rhel') + should_not contain_exec('rpm --import http://www.rabbitmq.com/rabbitmq-signing-key-public.asc') + end + end + + context 'on Redhat' do + let(:params) {{ :manage_repos => true }} + let(:facts) {{ :osfamily => 'RedHat' }} + it 'does import repo public key when manage_repos is true' do + should contain_class('rabbitmq::repo::rhel') + should contain_exec('rpm --import http://www.rabbitmq.com/rabbitmq-signing-key-public.asc') + end + end + + context 'on Redhat' do + let(:params) {{ :manage_repos => false, :repos_ensure => true }} + let(:facts) {{ :osfamily => 'RedHat' }} + it 'does not import repo public key when manage_repos is false and repos_ensure is true' do + should_not contain_class('rabbitmq::repo::rhel') + should_not contain_exec('rpm --import http://www.rabbitmq.com/rabbitmq-signing-key-public.asc') + end + end + + context 'on Redhat' do + let(:params) {{ :manage_repos => true, :repos_ensure => true }} + let(:facts) {{ :osfamily => 'RedHat' }} + it 'does import repo public key when manage_repos is true and repos_ensure is true' do + should contain_class('rabbitmq::repo::rhel') + should contain_exec('rpm --import http://www.rabbitmq.com/rabbitmq-signing-key-public.asc') + end + end + + context 'on Redhat' do + let(:params) {{ :manage_repos => false, :repos_ensure => false }} + let(:facts) {{ :osfamily => 'RedHat' }} + it 'does not import repo public key when manage_repos is false and repos_ensure is false' do + should_not contain_class('rabbitmq::repo::rhel') + should_not contain_exec('rpm --import http://www.rabbitmq.com/rabbitmq-signing-key-public.asc') + end + end + + context 'on Redhat' do + let(:params) {{ :manage_repos => true, :repos_ensure => false }} + let(:facts) {{ :osfamily => 'RedHat' }} + it 'does not import repo public key when manage_repos is true and repos_ensure is false' do + should contain_class('rabbitmq::repo::rhel') + should_not contain_exec('rpm --import http://www.rabbitmq.com/rabbitmq-signing-key-public.asc') end end @@ -54,7 +223,6 @@ context "on #{distro}" do let(:facts) {{ :osfamily => distro, - :rabbitmq_erlang_cookie => 'EOKOWXQREETZSHFNTPEY', :lsbdistcodename => 'squeeze', :lsbdistid => 'Debian' }} @@ -98,14 +266,6 @@ end end - context 'deprecated parameters' do - describe 'cluster_disk_nodes' do - let(:params) {{ :cluster_disk_nodes => ['node1', 'node2'] }} - - it { should contain_notify('cluster_disk_nodes') } - end - end - describe 'manages configuration directory correctly' do it { should contain_file('/etc/rabbitmq').with( 'ensure' => 'directory' @@ -117,22 +277,21 @@ end context 'configures config_cluster' do - let(:facts) {{ :osfamily => distro, :rabbitmq_erlang_cookie => 'ORIGINAL', :lsbdistid => 'Debian' }} + let(:facts) {{ :osfamily => distro, :lsbdistid => 'Debian' }} let(:params) {{ :config_cluster => true, :cluster_nodes => ['hare-1', 'hare-2'], :cluster_node_type => 'ram', - :erlang_cookie => 'TESTCOOKIE', :wipe_db_on_cookie_change => false }} describe 'with defaults' do it 'fails' do - expect{subject}.to raise_error(/^ERROR: The current erlang cookie is ORIGINAL/) + expect{subject}.to raise_error(/^You must set the \$erlang_cookie value/) end end - describe 'with wipe_db_on_cookie_change set' do + describe 'with erlang_cookie set' do let(:params) {{ :config_cluster => true, :cluster_nodes => ['hare-1', 'hare-2'], @@ -140,22 +299,8 @@ :erlang_cookie => 'TESTCOOKIE', :wipe_db_on_cookie_change => true }} - it 'wipes the database' do - should contain_exec('wipe_db') - should contain_file('erlang_cookie') - end - end - - describe 'correctly when cookies match' do - let(:params) {{ - :config_cluster => true, - :cluster_nodes => ['hare-1', 'hare-2'], - :cluster_node_type => 'ram', - :erlang_cookie => 'ORIGINAL', - :wipe_db_on_cookie_change => true - }} - it 'and doesnt wipe anything' do - should contain_file('erlang_cookie') + it 'contains the rabbitmq_erlang_cookie' do + should contain_rabbitmq_erlang_cookie('/var/lib/rabbitmq/.erlang.cookie') end end @@ -173,35 +318,30 @@ }) end - it 'for erlang_cookie' do - should contain_file('erlang_cookie').with({ - 'content' => 'ORIGINAL', - }) - end end end describe 'rabbitmq-env configuration' do let(:params) {{ :environment_variables => { - 'RABBITMQ_NODE_IP_ADDRESS' => '1.1.1.1', - 'RABBITMQ_NODE_PORT' => '5656', - 'RABBITMQ_NODENAME' => 'HOSTNAME', - 'RABBITMQ_SERVICENAME' => 'RabbitMQ', - 'RABBITMQ_CONSOLE_LOG' => 'RabbitMQ.debug', - 'RABBITMQ_CTL_ERL_ARGS' => 'verbose', - 'RABBITMQ_SERVER_ERL_ARGS' => 'v', - 'RABBITMQ_SERVER_START_ARGS' => 'debug' + 'NODE_IP_ADDRESS' => '1.1.1.1', + 'NODE_PORT' => '5656', + 'NODENAME' => 'HOSTNAME', + 'SERVICENAME' => 'RabbitMQ', + 'CONSOLE_LOG' => 'RabbitMQ.debug', + 'CTL_ERL_ARGS' => 'verbose', + 'SERVER_ERL_ARGS' => 'v', + 'SERVER_START_ARGS' => 'debug' }}} it 'should set environment variables' do should contain_file('rabbitmq-env.config') \ - .with_content(/RABBITMQ_NODE_IP_ADDRESS=1.1.1.1/) \ - .with_content(/RABBITMQ_NODE_PORT=5656/) \ - .with_content(/RABBITMQ_NODENAME=HOSTNAME/) \ - .with_content(/RABBITMQ_SERVICENAME=RabbitMQ/) \ - .with_content(/RABBITMQ_CONSOLE_LOG=RabbitMQ.debug/) \ - .with_content(/RABBITMQ_CTL_ERL_ARGS=verbose/) \ - .with_content(/RABBITMQ_SERVER_ERL_ARGS=v/) \ - .with_content(/RABBITMQ_SERVER_START_ARGS=debug/) + .with_content(/NODE_IP_ADDRESS=1.1.1.1/) \ + .with_content(/NODE_PORT=5656/) \ + .with_content(/NODENAME=HOSTNAME/) \ + .with_content(/SERVICENAME=RabbitMQ/) \ + .with_content(/CONSOLE_LOG=RabbitMQ.debug/) \ + .with_content(/CTL_ERL_ARGS=verbose/) \ + .with_content(/SERVER_ERL_ARGS=v/) \ + .with_content(/SERVER_START_ARGS=debug/) end end @@ -224,9 +364,9 @@ context 'configuration setting' do describe 'node_ip_address when set' do let(:params) {{ :node_ip_address => '172.0.0.1' }} - it 'should set RABBITMQ_NODE_IP_ADDRESS to specified value' do + it 'should set NODE_IP_ADDRESS to specified value' do should contain_file('rabbitmq-env.config'). - with_content(%r{RABBITMQ_NODE_IP_ADDRESS=172\.0\.0\.1}) + with_content(%r{NODE_IP_ADDRESS=172\.0\.0\.1}) end end @@ -277,7 +417,7 @@ it { should contain_rabbitmq_plugin('rabbitmq_auth_backend_ldap') } it 'should contain ldap parameters' do - verify_contents(subject, 'rabbitmq.config', + verify_contents(subject, 'rabbitmq.config', ['[', ' {rabbit, [', ' {auth_backends, [rabbit_auth_backend_internal, rabbit_auth_backend_ldap]},', ' ]}', ' {rabbitmq_auth_backend_ldap, [', ' {other_bind, anon},', ' {servers, ["ldap.example.com"]},', @@ -301,7 +441,7 @@ it { should contain_rabbitmq_plugin('rabbitmq_auth_backend_ldap') } it 'should contain ldap parameters' do - verify_contents(subject, 'rabbitmq.config', + verify_contents(subject, 'rabbitmq.config', ['[', ' {rabbit, [', ' {auth_backends, [rabbit_auth_backend_internal, rabbit_auth_backend_ldap]},', ' ]}', ' {rabbitmq_auth_backend_ldap, [', ' {other_bind, anon},', ' {servers, ["ldap.example.com"]},', @@ -363,6 +503,79 @@ end end + describe 'ssl options with specific ssl versions' do + let(:params) { + { :ssl => true, + :ssl_port => 3141, + :ssl_cacert => '/path/to/cacert', + :ssl_cert => '/path/to/cert', + :ssl_key => '/path/to/key', + :ssl_versions => ['tlsv1.2', 'tlsv1.1'] + } } + + it 'should set ssl options to specified values' do + should contain_file('rabbitmq.config').with_content(%r{ssl_listeners, \[3141\]}) + should contain_file('rabbitmq.config').with_content(%r{ssl_options, \[\{cacertfile,"/path/to/cacert"}) + should contain_file('rabbitmq.config').with_content(%r{certfile,"/path/to/cert"}) + should contain_file('rabbitmq.config').with_content(%r{keyfile,"/path/to/key}) + should contain_file('rabbitmq.config').with_content(%r{ssl, \[\{versions, \['tlsv1.1', 'tlsv1.2'\]\}\]}) + should contain_file('rabbitmq.config').with_content(%r{versions, \['tlsv1.1', 'tlsv1.2'\]}) + end + end + + describe 'ssl options with invalid ssl_versions type' do + let(:params) { + { :ssl => true, + :ssl_port => 3141, + :ssl_cacert => '/path/to/cacert', + :ssl_cert => '/path/to/cert', + :ssl_key => '/path/to/key', + :ssl_versions => 'tlsv1.2, tlsv1.1' + } } + + it 'fails' do + expect{subject}.to raise_error(/is not an Array/) + end + end + + describe 'ssl options with ssl_versions and not ssl' do + let(:params) { + { :ssl => false, + :ssl_port => 3141, + :ssl_cacert => '/path/to/cacert', + :ssl_cert => '/path/to/cert', + :ssl_key => '/path/to/key', + :ssl_versions => ['tlsv1.2', 'tlsv1.1'] + } } + + it 'fails' do + expect{subject}.to raise_error(/^\$ssl_versions requires that \$ssl => true/) + end + end + + describe 'ssl admin options with specific ssl versions' do + let(:params) { + { :ssl => true, + :ssl_management_port => 5926, + :ssl_cacert => '/path/to/cacert', + :ssl_cert => '/path/to/cert', + :ssl_key => '/path/to/key', + :ssl_versions => ['tlsv1.2', 'tlsv1.1'], + :admin_enable => true + } } + + it 'should set admin ssl opts to specified values' do + should contain_file('rabbitmq.config').with_content(%r{rabbitmq_management, \[}) + should contain_file('rabbitmq.config').with_content(%r{listener, \[}) + should contain_file('rabbitmq.config').with_content(%r{port, 5926\}}) + should contain_file('rabbitmq.config').with_content(%r{ssl, true\}}) + should contain_file('rabbitmq.config').with_content(%r{ssl_opts, \[\{cacertfile, "/path/to/cacert"\},}) + should contain_file('rabbitmq.config').with_content(%r{certfile, "/path/to/cert"\},}) + should contain_file('rabbitmq.config').with_content(%r{keyfile, "/path/to/key"\}}) + should contain_file('rabbitmq.config').with_content(%r{,\{versions, \['tlsv1.1', 'tlsv1.2'\]\}[\r\n ]*\]\}}) + end + end + describe 'ssl admin options' do let(:params) { { :ssl => true, @@ -380,7 +593,7 @@ should contain_file('rabbitmq.config').with_content(%r{ssl, true\}}) should contain_file('rabbitmq.config').with_content(%r{ssl_opts, \[\{cacertfile, "/path/to/cacert"\},}) should contain_file('rabbitmq.config').with_content(%r{certfile, "/path/to/cert"\},}) - should contain_file('rabbitmq.config').with_content(%r{keyfile, "/path/to/key"\}\]\}}) + should contain_file('rabbitmq.config').with_content(%r{keyfile, "/path/to/key"\}[\r\n ]*\]\}}) end end @@ -415,7 +628,7 @@ should contain_file('rabbitmq.config').with_content(%r{ssl, true\},}) should contain_file('rabbitmq.config').with_content(%r{ssl_opts, \[\{cacertfile, "/path/to/cacert"\},}) should contain_file('rabbitmq.config').with_content(%r{certfile, "/path/to/cert"\},}) - should contain_file('rabbitmq.config').with_content(%r{keyfile, "/path/to/key"\}\]\}}) + should contain_file('rabbitmq.config').with_content(%r{keyfile, "/path/to/key"\}[\r\n ]*\]\}}) end end @@ -460,7 +673,7 @@ it 'should set config variables' do should contain_file('rabbitmq.config') \ .with_content(/\{inet_dist_listen_min, 9100\}/) \ - .with_content(/\{inet_dist_listen_max, 9105\}/) + .with_content(/\{inet_dist_listen_max, 9105\}/) end end @@ -564,7 +777,7 @@ should contain_package('rabbitmq-server').with( 'ensure' => 'installed', 'name' => 'rabbitmq-server', - 'provider' => 'yum', + 'provider' => 'rpm', 'source' => 'http://www.rabbitmq.com/releases/rabbitmq-server/v3.2.3/rabbitmq-server-3.2.3-1.noarch.rpm' ) end @@ -602,7 +815,7 @@ 'release' => 'testing', 'repos' => 'main', 'include_src' => false, - 'key' => '056E8E56' + 'key' => 'F7B8CEA6056E8E56' ) } end end @@ -616,7 +829,7 @@ 'release' => 'testing', 'repos' => 'main', 'include_src' => false, - 'key' => '056E8E56' + 'key' => 'F7B8CEA6056E8E56' ) } it { should contain_apt__pin('rabbitmq').with( diff --git a/rabbitmq/spec/spec_helper_acceptance.rb b/rabbitmq/spec/spec_helper_acceptance.rb index 1dbc82a86..4c52dee15 100644 --- a/rabbitmq/spec/spec_helper_acceptance.rb +++ b/rabbitmq/spec/spec_helper_acceptance.rb @@ -20,8 +20,8 @@ # Readable test descriptions c.formatter = :documentation c.before :suite do - puppet_module_install(:source => proj_root, :module_name => 'rabbitmq') hosts.each do |host| + copy_module_to(host, :source => proj_root, :module_name => 'rabbitmq') shell("/bin/touch #{default['puppetpath']}/hiera.yaml") shell('puppet module install puppetlabs-stdlib', { :acceptable_exit_codes => [0,1] }) diff --git a/rabbitmq/spec/unit/facts/rabbitmq_erlang_cookie_spec.rb b/rabbitmq/spec/unit/facts/rabbitmq_erlang_cookie_spec.rb deleted file mode 100644 index f4daf79bd..000000000 --- a/rabbitmq/spec/unit/facts/rabbitmq_erlang_cookie_spec.rb +++ /dev/null @@ -1,19 +0,0 @@ -require 'spec_helper' - -describe 'rabbitmq_erlang_cookie', :type => :fact do - before(:each) { Facter.clear } - - it 'works correctly' do - Facter.fact(:osfamily).stubs(:value).returns('RedHat') - File.stubs(:exists?).with('/var/lib/rabbitmq/.erlang.cookie').returns(true) - File.stubs(:read).with('/var/lib/rabbitmq/.erlang.cookie').returns('THISISACOOKIE') - Facter.fact(:rabbitmq_erlang_cookie).value.should == 'THISISACOOKIE' - end - - it 'fails if file doesnt exist' do - Facter.fact(:osfamily).stubs(:value).returns('RedHat') - File.stubs(:exists?).with('/var/lib/rabbitmq/.erlang.cookie').returns(false) - Facter.fact(:rabbitmq_erlang_cookie).value.should == nil - end - -end diff --git a/rabbitmq/spec/unit/puppet/provider/rabbitmq_binding/rabbitmqadmin_spec.rb b/rabbitmq/spec/unit/puppet/provider/rabbitmq_binding/rabbitmqadmin_spec.rb new file mode 100644 index 000000000..d1ff0667c --- /dev/null +++ b/rabbitmq/spec/unit/puppet/provider/rabbitmq_binding/rabbitmqadmin_spec.rb @@ -0,0 +1,59 @@ +require 'puppet' +require 'mocha/api' +RSpec.configure do |config| + config.mock_with :mocha +end +provider_class = Puppet::Type.type(:rabbitmq_binding).provider(:rabbitmqadmin) +describe provider_class do + before :each do + @resource = Puppet::Type::Rabbitmq_binding.new( + {:name => 'source@target@/', + :destination_type => :queue, + :routing_key => 'blablub', + :arguments => {} + } + ) + @provider = provider_class.new(@resource) + end + + it 'should return instances' do + provider_class.expects(:rabbitmqctl).with('list_vhosts', '-q').returns <<-EOT +/ +EOT + provider_class.expects(:rabbitmqctl).with('list_bindings', '-q', '-p', '/', 'source_name', 'destination_name', 'destination_kind', 'routing_key', 'arguments').returns <<-EOT + queue queue queue [] +EOT + instances = provider_class.instances + instances.size.should == 1 + end + + it 'should call rabbitmqadmin to create' do + @provider.expects(:rabbitmqadmin).with('declare', 'binding', '--vhost=/', '--user=guest', '--password=guest', 'source=source', 'destination=target', 'arguments={}', 'routing_key=blablub', 'destination_type=queue') + @provider.create + end + + it 'should call rabbitmqadmin to destroy' do + @provider.expects(:rabbitmqadmin).with('delete', 'binding', '--vhost=/', '--user=guest', '--password=guest', 'source=source', 'destination_type=queue', 'destination=target') + @provider.destroy + end + + context 'specifying credentials' do + before :each do + @resource = Puppet::Type::Rabbitmq_binding.new( + {:name => 'source@test2@/', + :destination_type => :queue, + :routing_key => 'blablubd', + :arguments => {}, + :user => 'colin', + :password => 'secret' + } + ) + @provider = provider_class.new(@resource) + end + + it 'should call rabbitmqadmin to create' do + @provider.expects(:rabbitmqadmin).with('declare', 'binding', '--vhost=/', '--user=colin', '--password=secret', 'source=source', 'destination=test2', 'arguments={}', 'routing_key=blablubd', 'destination_type=queue') + @provider.create + end + end +end diff --git a/rabbitmq/spec/unit/puppet/provider/rabbitmq_exchange/rabbitmqadmin_spec.rb b/rabbitmq/spec/unit/puppet/provider/rabbitmq_exchange/rabbitmqadmin_spec.rb index ac68970cf..89d6e94e3 100644 --- a/rabbitmq/spec/unit/puppet/provider/rabbitmq_exchange/rabbitmqadmin_spec.rb +++ b/rabbitmq/spec/unit/puppet/provider/rabbitmq_exchange/rabbitmqadmin_spec.rb @@ -36,12 +36,12 @@ end it 'should call rabbitmqadmin to create' do - @provider.expects(:rabbitmqadmin).with('declare', 'exchange', '--vhost=/', '--user=guest', '--password=guest', 'name=amq.direct', 'type=topic') + @provider.expects(:rabbitmqadmin).with('declare', 'exchange', '--vhost=/', '--user=guest', '--password=guest', 'name=amq.direct', 'type=topic', '-c', '/etc/rabbitmq/rabbitmqadmin.conf') @provider.create end it 'should call rabbitmqadmin to destroy' do - @provider.expects(:rabbitmqadmin).with('delete', 'exchange', '--vhost=/', '--user=guest', '--password=guest', 'name=amq.direct') + @provider.expects(:rabbitmqadmin).with('delete', 'exchange', '--vhost=/', '--user=guest', '--password=guest', 'name=amq.direct', '-c', '/etc/rabbitmq/rabbitmqadmin.conf') @provider.destroy end @@ -58,7 +58,7 @@ end it 'should call rabbitmqadmin to create' do - @provider.expects(:rabbitmqadmin).with('declare', 'exchange', '--vhost=/', '--user=colin', '--password=secret', 'name=amq.direct', 'type=topic') + @provider.expects(:rabbitmqadmin).with('declare', 'exchange', '--vhost=/', '--user=colin', '--password=secret', 'name=amq.direct', 'type=topic', '-c', '/etc/rabbitmq/rabbitmqadmin.conf') @provider.create end end diff --git a/rabbitmq/spec/unit/puppet/provider/rabbitmq_plugin/rabbitmqctl_spec.rb b/rabbitmq/spec/unit/puppet/provider/rabbitmq_plugin/rabbitmqctl_spec.rb new file mode 100644 index 000000000..c398b6292 --- /dev/null +++ b/rabbitmq/spec/unit/puppet/provider/rabbitmq_plugin/rabbitmqctl_spec.rb @@ -0,0 +1,26 @@ +require 'puppet' +require 'mocha' +RSpec.configure do |config| + config.mock_with :mocha +end +provider_class = Puppet::Type.type(:rabbitmq_plugin).provider(:rabbitmqplugins) +describe provider_class do + before :each do + @resource = Puppet::Type::Rabbitmq_plugin.new( + {:name => 'foo'} + ) + @provider = provider_class.new(@resource) + end + it 'should match plugins' do + @provider.expects(:rabbitmqplugins).with('list', '-E', '-m').returns("foo\n") + @provider.exists?.should == 'foo' + end + it 'should call rabbitmqplugins to enable' do + @provider.expects(:rabbitmqplugins).with('enable', 'foo') + @provider.create + end + it 'should call rabbitmqplugins to disable' do + @provider.expects(:rabbitmqplugins).with('disable', 'foo') + @provider.destroy + end +end diff --git a/rabbitmq/spec/unit/puppet/provider/rabbitmq_policy/rabbitmqctl_spec.rb b/rabbitmq/spec/unit/puppet/provider/rabbitmq_policy/rabbitmqctl_spec.rb new file mode 100644 index 000000000..cddb6c0c0 --- /dev/null +++ b/rabbitmq/spec/unit/puppet/provider/rabbitmq_policy/rabbitmqctl_spec.rb @@ -0,0 +1,114 @@ +require 'puppet' +require 'mocha' + +RSpec.configure do |config| + config.mock_with :mocha +end + +describe Puppet::Type.type(:rabbitmq_policy).provider(:rabbitmqctl) do + + let(:resource) do + Puppet::Type.type(:rabbitmq_policy).new( + :name => 'ha-all@/', + :pattern => '.*', + :definition => { + 'ha-mode' => 'all' + }, + :provider => described_class.name + ) + end + + let(:provider) { resource.provider } + + after(:each) do + described_class.instance_variable_set(:@policies, nil) + end + + it 'should accept @ in policy name' do + resource = Puppet::Type.type(:rabbitmq_policy).new( + :name => 'ha@home@/', + :pattern => '.*', + :definition => { + 'ha-mode' => 'all' + }, + :provider => described_class.name + ) + provider = described_class.new(resource) + provider.should_policy.should == 'ha@home' + provider.should_vhost.should == '/' + end + + it 'should fail with invalid output from list' do + provider.class.expects(:rabbitmqctl).with('list_policies', '-q', '-p', '/').returns 'foobar' + expect { provider.exists? }.to raise_error(Puppet::Error, /cannot parse line from list_policies/) + end + + it 'should match policies from list (>=3.2.0)' do + provider.class.expects(:rabbitmqctl).with('list_policies', '-q', '-p', '/').returns <<-EOT +/ ha-all all .* {"ha-mode":"all","ha-sync-mode":"automatic"} 0 +/ test exchanges .* {"ha-mode":"all"} 0 +EOT + provider.exists?.should == { + :applyto => 'all', + :pattern => '.*', + :priority => '0', + :definition => { + 'ha-mode' => 'all', + 'ha-sync-mode' => 'automatic'} + } + end + + it 'should match policies from list (<3.2.0)' do + provider.class.expects(:rabbitmqctl).with('list_policies', '-q', '-p', '/').returns <<-EOT +/ ha-all .* {"ha-mode":"all","ha-sync-mode":"automatic"} 0 +/ test .* {"ha-mode":"all"} 0 +EOT + provider.exists?.should == { + :applyto => 'all', + :pattern => '.*', + :priority => '0', + :definition => { + 'ha-mode' => 'all', + 'ha-sync-mode' => 'automatic'} + } + end + + it 'should not match an empty list' do + provider.class.expects(:rabbitmqctl).with('list_policies', '-q', '-p', '/').returns '' + provider.exists?.should == nil + end + + it 'should destroy policy' do + provider.expects(:rabbitmqctl).with('clear_policy', '-p', '/', 'ha-all') + provider.destroy + end + + it 'should only call set_policy once (<3.2.0)' do + provider.class.expects(:rabbitmq_version).returns '3.1.0' + provider.resource[:priority] = '10' + provider.resource[:applyto] = 'exchanges' + provider.expects(:rabbitmqctl).with('set_policy', + '-p', '/', + 'ha-all', + '.*', + '{"ha-mode":"all"}', + '10').once + provider.priority = '10' + provider.applyto = 'exchanges' + end + + it 'should only call set_policy once (>=3.2.0)' do + provider.class.expects(:rabbitmq_version).returns '3.2.0' + provider.resource[:priority] = '10' + provider.resource[:applyto] = 'exchanges' + provider.expects(:rabbitmqctl).with('set_policy', + '-p', '/', + '--priority', '10', + '--apply-to', 'exchanges', + 'ha-all', + '.*', + '{"ha-mode":"all"}').once + provider.priority = '10' + provider.applyto = 'exchanges' + end +end diff --git a/rabbitmq/spec/unit/puppet/provider/rabbitmq_queue/rabbitmqadmin_spec.rb b/rabbitmq/spec/unit/puppet/provider/rabbitmq_queue/rabbitmqadmin_spec.rb new file mode 100644 index 000000000..97410a8b4 --- /dev/null +++ b/rabbitmq/spec/unit/puppet/provider/rabbitmq_queue/rabbitmqadmin_spec.rb @@ -0,0 +1,60 @@ +require 'puppet' +require 'mocha/api' +RSpec.configure do |config| + config.mock_with :mocha +end +provider_class = Puppet::Type.type(:rabbitmq_queue).provider(:rabbitmqadmin) +describe provider_class do + before :each do + @resource = Puppet::Type::Rabbitmq_queue.new( + {:name => 'test@/', + :durable => :true, + :auto_delete => :false, + :arguments => {} + } + ) + @provider = provider_class.new(@resource) + end + + it 'should return instances' do + provider_class.expects(:rabbitmqctl).with('list_vhosts', '-q').returns <<-EOT +/ +EOT + provider_class.expects(:rabbitmqctl).with('list_queues', '-q', '-p', '/', 'name', 'durable', 'auto_delete', 'arguments').returns <<-EOT +test true false [] +test2 true false [{"x-message-ttl",342423},{"x-expires",53253232},{"x-max-length",2332},{"x-max-length-bytes",32563324242},{"x-dead-letter-exchange","amq.direct"},{"x-dead-letter-routing-key","test.routing"}] +EOT + instances = provider_class.instances + instances.size.should == 2 + end + + it 'should call rabbitmqadmin to create' do + @provider.expects(:rabbitmqadmin).with('declare', 'queue', '--vhost=/', '--user=guest', '--password=guest', 'name=test', 'durable=true', 'auto_delete=false', 'arguments={}') + @provider.create + end + + it 'should call rabbitmqadmin to destroy' do + @provider.expects(:rabbitmqadmin).with('delete', 'queue', '--vhost=/', '--user=guest', '--password=guest', 'name=test') + @provider.destroy + end + + context 'specifying credentials' do + before :each do + @resource = Puppet::Type::Rabbitmq_queue.new( + {:name => 'test@/', + :durable => 'true', + :auto_delete => 'false', + :arguments => {}, + :user => 'colin', + :password => 'secret', + } + ) + @provider = provider_class.new(@resource) + end + + it 'should call rabbitmqadmin to create' do + @provider.expects(:rabbitmqadmin).with('declare', 'queue', '--vhost=/', '--user=colin', '--password=secret', 'name=test', 'durable=true', 'auto_delete=false', 'arguments={}') + @provider.create + end + end +end diff --git a/rabbitmq/spec/unit/puppet/provider/rabbitmq_user/rabbitmqctl_spec.rb b/rabbitmq/spec/unit/puppet/provider/rabbitmq_user/rabbitmqctl_spec.rb index 2c13b886a..2012ccc05 100644 --- a/rabbitmq/spec/unit/puppet/provider/rabbitmq_user/rabbitmqctl_spec.rb +++ b/rabbitmq/spec/unit/puppet/provider/rabbitmq_user/rabbitmqctl_spec.rb @@ -12,44 +12,34 @@ @provider = provider_class.new(@resource) end it 'should match user names' do - @provider.expects(:rabbitmqctl).with('list_users').returns <<-EOT -Listing users ... + @provider.expects(:rabbitmqctl).with('-q', 'list_users').returns <<-EOT foo -...done. EOT @provider.exists?.should == 'foo' end it 'should match user names with 2.4.1 syntax' do - @provider.expects(:rabbitmqctl).with('list_users').returns <<-EOT -Listing users ... + @provider.expects(:rabbitmqctl).with('-q', 'list_users').returns <<-EOT foo bar -...done. EOT @provider.exists?.should == 'foo bar' end it 'should not match if no users on system' do - @provider.expects(:rabbitmqctl).with('list_users').returns <<-EOT -Listing users ... -...done. + @provider.expects(:rabbitmqctl).with('-q', 'list_users').returns <<-EOT EOT @provider.exists?.should be_nil end it 'should not match if no matching users on system' do - @provider.expects(:rabbitmqctl).with('list_users').returns <<-EOT -Listing users ... + @provider.expects(:rabbitmqctl).with('-q', 'list_users').returns <<-EOT fooey -...done. EOT @provider.exists?.should be_nil end it 'should match user names from list' do - @provider.expects(:rabbitmqctl).with('list_users').returns <<-EOT -Listing users ... + @provider.expects(:rabbitmqctl).with('-q', 'list_users').returns <<-EOT one two three foo bar -...done. EOT @provider.exists?.should == 'foo' end @@ -62,13 +52,11 @@ @resource[:password] = 'bar' @resource[:admin] = 'true' @provider.expects(:rabbitmqctl).with('add_user', 'foo', 'bar') - @provider.expects(:rabbitmqctl).with('list_users').returns <<-EOT -Listing users ... + @provider.expects(:rabbitmqctl).with('-q', 'list_users').returns <<-EOT foo [] icinga [monitoring] kitchen [] kitchen2 [abc, def, ghi] -...done. EOT @provider.expects(:rabbitmqctl).with('set_user_tags', 'foo', ['administrator']) @provider.create @@ -78,99 +66,81 @@ @provider.destroy end it 'should be able to retrieve admin value' do - @provider.expects(:rabbitmqctl).with('list_users').returns <<-EOT -Listing users ... + @provider.expects(:rabbitmqctl).with('-q', 'list_users').returns <<-EOT foo [administrator] -...done. EOT @provider.admin.should == :true - @provider.expects(:rabbitmqctl).with('list_users').returns <<-EOT -Listing users ... + @provider.expects(:rabbitmqctl).with('-q', 'list_users').returns <<-EOT one [administrator] foo [] -...done. EOT @provider.admin.should == :false end it 'should fail if admin value is invalid' do - @provider.expects(:rabbitmqctl).with('list_users').returns <<-EOT -Listing users ... + @provider.expects(:rabbitmqctl).with('-q', 'list_users').returns <<-EOT foo fail -...done. EOT expect { @provider.admin }.to raise_error(Puppet::Error, /Could not match line/) end it 'should be able to set admin value' do - @provider.expects(:rabbitmqctl).with('list_users').returns <<-EOT -Listing users ... + @provider.expects(:rabbitmqctl).with('-q', 'list_users').returns <<-EOT foo [] icinga [monitoring] kitchen [] kitchen2 [abc, def, ghi] -...done. EOT @provider.expects(:rabbitmqctl).with('set_user_tags', 'foo', ['administrator']) @provider.admin=:true end it 'should not interfere with existing tags on the user when setting admin value' do - @provider.expects(:rabbitmqctl).with('list_users').returns <<-EOT -Listing users ... + @provider.expects(:rabbitmqctl).with('-q', 'list_users').returns <<-EOT foo [bar, baz] icinga [monitoring] kitchen [] kitchen2 [abc, def, ghi] -...done. EOT - @provider.expects(:rabbitmqctl).with('set_user_tags', 'foo', ['bar','baz', 'administrator'].sort) + @provider.expects(:rabbitmqctl).with('set_user_tags', 'foo', ['bar','baz', 'administrator'].sort) @provider.admin=:true end it 'should be able to unset admin value' do - @provider.expects(:rabbitmqctl).with('list_users').returns <<-EOT -Listing users ... + @provider.expects(:rabbitmqctl).with('-q', 'list_users').returns <<-EOT foo [administrator] guest [administrator] icinga [] -...done. EOT @provider.expects(:rabbitmqctl).with('set_user_tags', 'foo', []) @provider.admin=:false end it 'should not interfere with existing tags on the user when unsetting admin value' do - @provider.expects(:rabbitmqctl).with('list_users').returns <<-EOT -Listing users ... + @provider.expects(:rabbitmqctl).with('-q', 'list_users').returns <<-EOT foo [administrator, bar, baz] icinga [monitoring] kitchen [] kitchen2 [abc, def, ghi] -...done. EOT - @provider.expects(:rabbitmqctl).with('set_user_tags', 'foo', ['bar','baz'].sort) + @provider.expects(:rabbitmqctl).with('set_user_tags', 'foo', ['bar','baz'].sort) @provider.admin=:false end it 'should clear all tags on existing user' do - @provider.expects(:rabbitmqctl).with('list_users').returns <<-EOT -Listing users ... + @provider.expects(:rabbitmqctl).with('-q', 'list_users').returns <<-EOT one [administrator] foo [tag1,tag2] icinga [monitoring] kitchen [] kitchen2 [abc, def, ghi] -...done. EOT @provider.expects(:rabbitmqctl).with('set_user_tags', 'foo', []) @provider.tags=[] end it 'should set multiple tags' do - @provider.expects(:rabbitmqctl).with('list_users').returns <<-EOT -Listing users ... + @provider.expects(:rabbitmqctl).with('-q', 'list_users').returns <<-EOT one [administrator] foo [] icinga [monitoring] kitchen [] kitchen2 [abc, def, ghi] -...done. EOT @provider.expects(:rabbitmqctl).with('set_user_tags', 'foo', ['tag1','tag2']) @provider.tags=['tag1','tag2'] @@ -178,14 +148,12 @@ it 'should clear tags while keep admin tag' do @resource[:admin] = true - @provider.expects(:rabbitmqctl).with('list_users').returns <<-EOT -Listing users ... + @provider.expects(:rabbitmqctl).with('-q', 'list_users').returns <<-EOT one [administrator] foo [administrator, tag1, tag2] icinga [monitoring] kitchen [] kitchen2 [abc, def, ghi] -...done. EOT @provider.expects(:rabbitmqctl).with('set_user_tags', 'foo', ["administrator"]) @provider.tags=[] @@ -193,14 +161,12 @@ it 'should change tags while keep admin tag' do @resource[:admin] = true - @provider.expects(:rabbitmqctl).with('list_users').returns <<-EOT -Listing users ... + @provider.expects(:rabbitmqctl).with('-q', 'list_users').returns <<-EOT one [administrator] foo [administrator, tag1, tag2] icinga [monitoring] kitchen [] kitchen2 [abc, def, ghi] -...done. EOT @provider.expects(:rabbitmqctl).with('set_user_tags', 'foo', ["administrator","tag1","tag3","tag7"]) @provider.tags=['tag1','tag7','tag3'] @@ -210,10 +176,8 @@ @resource[:tags] = [ "tag1", "tag2" ] @provider.expects(:rabbitmqctl).with('add_user', 'foo', 'bar') @provider.expects(:rabbitmqctl).with('set_user_tags', 'foo', ["tag1","tag2"]) - @provider.expects(:rabbitmqctl).with('list_users').returns <<-EOT -Listing users ... + @provider.expects(:rabbitmqctl).with('-q', 'list_users').returns <<-EOT foo [] -...done. EOT @provider.create end @@ -222,15 +186,12 @@ @resource[:tags] = [ "tag1", "tag2" ] @resource[:admin] = true @provider.expects(:rabbitmqctl).with('add_user', 'foo', 'bar') - @provider.expects(:rabbitmqctl).with('list_users').twice.returns <<-EOT -Listing users ... + @provider.expects(:rabbitmqctl).with('-q', 'list_users').twice.returns <<-EOT foo [] -...done. EOT @provider.expects(:rabbitmqctl).with('set_user_tags', 'foo', ["administrator"]) @provider.expects(:rabbitmqctl).with('set_user_tags', 'foo', ["administrator","tag1","tag2"]) @provider.create end - end diff --git a/rabbitmq/spec/unit/puppet/provider/rabbitmq_user_permissions/rabbitmqctl_spec.rb b/rabbitmq/spec/unit/puppet/provider/rabbitmq_user_permissions/rabbitmqctl_spec.rb index a8824fdf4..bdbc73e82 100644 --- a/rabbitmq/spec/unit/puppet/provider/rabbitmq_user_permissions/rabbitmqctl_spec.rb +++ b/rabbitmq/spec/unit/puppet/provider/rabbitmq_user_permissions/rabbitmqctl_spec.rb @@ -15,33 +15,25 @@ @provider_class.instance_variable_set(:@users, nil) end it 'should match user permissions from list' do - @provider.class.expects(:rabbitmqctl).with('list_user_permissions', 'foo').returns <<-EOT -Listing users ... + @provider.class.expects(:rabbitmqctl).with('-q', 'list_user_permissions', 'foo').returns <<-EOT bar 1 2 3 -...done. EOT @provider.exists?.should == {:configure=>"1", :write=>"2", :read=>"3"} end it 'should match user permissions with empty columns' do - @provider.class.expects(:rabbitmqctl).with('list_user_permissions', 'foo').returns <<-EOT -Listing users ... + @provider.class.expects(:rabbitmqctl).with('-q', 'list_user_permissions', 'foo').returns <<-EOT bar 3 -...done. EOT @provider.exists?.should == {:configure=>"", :write=>"", :read=>"3"} end it 'should not match user permissions with more than 3 columns' do - @provider.class.expects(:rabbitmqctl).with('list_user_permissions', 'foo').returns <<-EOT -Listing users ... + @provider.class.expects(:rabbitmqctl).with('-q', 'list_user_permissions', 'foo').returns <<-EOT bar 1 2 3 4 -...done. EOT expect { @provider.exists? }.to raise_error(Puppet::Error, /cannot parse line from list_user_permissions/) end it 'should not match an empty list' do - @provider.class.expects(:rabbitmqctl).with('list_user_permissions', 'foo').returns <<-EOT -Listing users ... -...done. + @provider.class.expects(:rabbitmqctl).with('-q', 'list_user_permissions', 'foo').returns <<-EOT EOT @provider.exists?.should == nil end @@ -49,30 +41,26 @@ @provider.instance_variable_set(:@should_vhost, "bar") @provider.instance_variable_set(:@should_user, "foo") @provider.expects(:rabbitmqctl).with('set_permissions', '-p', 'bar', 'foo', "''", "''", "''") - @provider.create + @provider.create end it 'should destroy permissions' do @provider.instance_variable_set(:@should_vhost, "bar") @provider.instance_variable_set(:@should_user, "foo") @provider.expects(:rabbitmqctl).with('clear_permissions', '-p', 'bar', 'foo') - @provider.destroy + @provider.destroy end {:configure_permission => '1', :write_permission => '2', :read_permission => '3'}.each do |k,v| it "should be able to retrieve #{k}" do - @provider.class.expects(:rabbitmqctl).with('list_user_permissions', 'foo').returns <<-EOT -Listing users ... + @provider.class.expects(:rabbitmqctl).with('-q', 'list_user_permissions', 'foo').returns <<-EOT bar 1 2 3 -...done. EOT @provider.send(k).should == v end end {:configure_permission => '1', :write_permission => '2', :read_permission => '3'}.each do |k,v| it "should be able to retrieve #{k} after exists has been called" do - @provider.class.expects(:rabbitmqctl).with('list_user_permissions', 'foo').returns <<-EOT -Listing users ... + @provider.class.expects(:rabbitmqctl).with('-q', 'list_user_permissions', 'foo').returns <<-EOT bar 1 2 3 -...done. EOT @provider.exists? @provider.send(k).should == v @@ -83,10 +71,8 @@ :write_permission => ['1', 'foo', '3'] }.each do |perm, columns| it "should be able to sync #{perm}" do - @provider.class.expects(:rabbitmqctl).with('list_user_permissions', 'foo').returns <<-EOT -Listing users ... + @provider.class.expects(:rabbitmqctl).with('-q', 'list_user_permissions', 'foo').returns <<-EOT bar 1 2 3 -...done. EOT @provider.resource[perm] = 'foo' @provider.expects(:rabbitmqctl).with('set_permissions', '-p', 'bar', 'foo', *columns) @@ -94,10 +80,8 @@ end end it 'should only call set_permissions once' do - @provider.class.expects(:rabbitmqctl).with('list_user_permissions', 'foo').returns <<-EOT -Listing users ... + @provider.class.expects(:rabbitmqctl).with('-q', 'list_user_permissions', 'foo').returns <<-EOT bar 1 2 3 -...done. EOT @provider.resource[:configure_permission] = 'foo' @provider.resource[:read_permission] = 'foo' diff --git a/rabbitmq/spec/unit/puppet/provider/rabbitmq_vhost/rabbitmqctl_spec.rb b/rabbitmq/spec/unit/puppet/provider/rabbitmq_vhost/rabbitmqctl_spec.rb index a1f89ad2c..6c8cce8df 100644 --- a/rabbitmq/spec/unit/puppet/provider/rabbitmq_vhost/rabbitmqctl_spec.rb +++ b/rabbitmq/spec/unit/puppet/provider/rabbitmq_vhost/rabbitmqctl_spec.rb @@ -12,7 +12,7 @@ @provider = provider_class.new(@resource) end it 'should match vhost names' do - @provider.expects(:rabbitmqctl).with('list_vhosts').returns <<-EOT + @provider.expects(:rabbitmqctl).with('-q', 'list_vhosts').returns <<-EOT Listing vhosts ... foo ...done. @@ -20,14 +20,14 @@ @provider.exists?.should == 'foo' end it 'should not match if no vhosts on system' do - @provider.expects(:rabbitmqctl).with('list_vhosts').returns <<-EOT + @provider.expects(:rabbitmqctl).with('-q', 'list_vhosts').returns <<-EOT Listing vhosts ... ...done. EOT @provider.exists?.should be_nil end it 'should not match if no matching vhosts on system' do - @provider.expects(:rabbitmqctl).with('list_vhosts').returns <<-EOT + @provider.expects(:rabbitmqctl).with('-q', 'list_vhosts').returns <<-EOT Listing vhosts ... fooey ...done. diff --git a/rabbitmq/spec/unit/puppet/type/rabbitmq_binding_spec.rb b/rabbitmq/spec/unit/puppet/type/rabbitmq_binding_spec.rb new file mode 100644 index 000000000..b0671e7c2 --- /dev/null +++ b/rabbitmq/spec/unit/puppet/type/rabbitmq_binding_spec.rb @@ -0,0 +1,50 @@ +require 'puppet' +require 'puppet/type/rabbitmq_binding' +describe Puppet::Type.type(:rabbitmq_binding) do + before :each do + @binding = Puppet::Type.type(:rabbitmq_binding).new( + :name => 'foo@blub@bar', + :destination_type => :queue + ) + end + it 'should accept an queue name' do + @binding[:name] = 'dan@dude@pl' + @binding[:name].should == 'dan@dude@pl' + end + it 'should require a name' do + expect { + Puppet::Type.type(:rabbitmq_binding).new({}) + }.to raise_error(Puppet::Error, 'Title or name must be provided') + end + it 'should not allow whitespace in the name' do + expect { + @binding[:name] = 'b r' + }.to raise_error(Puppet::Error, /Valid values match/) + end + it 'should not allow names without one @' do + expect { + @binding[:name] = 'b_r' + }.to raise_error(Puppet::Error, /Valid values match/) + end + + it 'should not allow names without two @' do + expect { + @binding[:name] = 'b@r' + }.to raise_error(Puppet::Error, /Valid values match/) + end + + it 'should accept an binding destination_type' do + @binding[:destination_type] = :exchange + @binding[:destination_type].should == :exchange + end + + it 'should accept a user' do + @binding[:user] = :root + @binding[:user].should == :root + end + + it 'should accept a password' do + @binding[:password] = :PaSsw0rD + @binding[:password].should == :PaSsw0rD + end +end diff --git a/rabbitmq/spec/unit/puppet/type/rabbitmq_policy_spec.rb b/rabbitmq/spec/unit/puppet/type/rabbitmq_policy_spec.rb new file mode 100644 index 000000000..2a8064a1a --- /dev/null +++ b/rabbitmq/spec/unit/puppet/type/rabbitmq_policy_spec.rb @@ -0,0 +1,91 @@ +require 'puppet' +require 'puppet/type/rabbitmq_policy' + +describe Puppet::Type.type(:rabbitmq_policy) do + + before do + @policy = Puppet::Type.type(:rabbitmq_policy).new( + :name => 'ha-all@/', + :pattern => '.*', + :definition => { + 'ha-mode' => 'all' + }) + end + + it 'should accept a valid name' do + @policy[:name] = 'ha-all@/' + @policy[:name].should == 'ha-all@/' + end + + it 'should require a name' do + expect { + Puppet::Type.type(:rabbitmq_policy).new({}) + }.to raise_error(Puppet::Error, 'Title or name must be provided') + end + + it 'should fail when name does not have a @' do + expect { + @policy[:name] = 'ha-all' + }.to raise_error(Puppet::Error, /Valid values match/) + end + + it 'should accept a valid regex for pattern' do + @policy[:pattern] = '.*?' + @policy[:pattern].should == '.*?' + end + + it 'should accept an empty string for pattern' do + @policy[:pattern] = '' + @policy[:pattern].should == '' + end + + it 'should not accept invalid regex for pattern' do + expect { + @policy[:pattern] = '*' + }.to raise_error(Puppet::Error, /Invalid regexp/) + end + + it 'should accept valid value for applyto' do + [:all, :exchanges, :queues].each do |v| + @policy[:applyto] = v + @policy[:applyto].should == v + end + end + + it 'should not accept invalid value for applyto' do + expect { + @policy[:applyto] = 'me' + }.to raise_error(Puppet::Error, /Invalid value/) + end + + it 'should accept a valid hash for definition' do + definition = {'ha-mode' => 'all', 'ha-sync-mode' => 'automatic'} + @policy[:definition] = definition + @policy[:definition].should == definition + end + + it 'should not accept invalid hash for definition' do + expect { + @policy[:definition] = 'ha-mode' + }.to raise_error(Puppet::Error, /Invalid definition/) + + expect { + @policy[:definition] = {'ha-mode' => ['a', 'b']} + }.to raise_error(Puppet::Error, /Invalid definition/) + end + + it 'should accept valid value for priority' do + [0, 10, '0', '10'].each do |v| + @policy[:priority] = v + @policy[:priority].should == v + end + end + + it 'should not accept invalid value for priority' do + ['-1', -1, '1.0', 1.0, 'abc', ''].each do |v| + expect { + @policy[:priority] = v + }.to raise_error(Puppet::Error, /Invalid value/) + end + end +end diff --git a/rabbitmq/spec/unit/puppet/type/rabbitmq_queue_spec.rb b/rabbitmq/spec/unit/puppet/type/rabbitmq_queue_spec.rb new file mode 100644 index 000000000..4fd7b34ef --- /dev/null +++ b/rabbitmq/spec/unit/puppet/type/rabbitmq_queue_spec.rb @@ -0,0 +1,60 @@ +require 'puppet' +require 'puppet/type/rabbitmq_queue' +require 'json' +describe Puppet::Type.type(:rabbitmq_queue) do + before :each do + @queue = Puppet::Type.type(:rabbitmq_queue).new( + :name => 'foo@bar', + :durable => :true, + :arguments => { + 'x-message-ttl' => 45, + 'x-dead-letter-exchange' => 'deadexchange' + } + ) + end + it 'should accept an queue name' do + @queue[:name] = 'dan@pl' + @queue[:name].should == 'dan@pl' + end + it 'should require a name' do + expect { + Puppet::Type.type(:rabbitmq_queue).new({}) + }.to raise_error(Puppet::Error, 'Title or name must be provided') + end + it 'should not allow whitespace in the name' do + expect { + @queue[:name] = 'b r' + }.to raise_error(Puppet::Error, /Valid values match/) + end + it 'should not allow names without @' do + expect { + @queue[:name] = 'b_r' + }.to raise_error(Puppet::Error, /Valid values match/) + end + + it 'should accept an arguments with numbers value' do + @queue[:arguments] = {'x-message-ttl' => 30} + @queue[:arguments].to_json.should == "{\"x-message-ttl\":30}" + @queue[:arguments]['x-message-ttl'].should == 30 + end + + it 'should accept an arguments with string value' do + @queue[:arguments] = {'x-dead-letter-exchange' => 'catchallexchange'} + @queue[:arguments].to_json.should == "{\"x-dead-letter-exchange\":\"catchallexchange\"}" + end + + it 'should accept an queue durable' do + @queue[:durable] = :true + @queue[:durable].should == :true + end + + it 'should accept a user' do + @queue[:user] = :root + @queue[:user].should == :root + end + + it 'should accept a password' do + @queue[:password] = :PaSsw0rD + @queue[:password].should == :PaSsw0rD + end +end diff --git a/rabbitmq/templates/rabbitmq.config.erb b/rabbitmq/templates/rabbitmq.config.erb index 8f6b14f75..591a1cb17 100644 --- a/rabbitmq/templates/rabbitmq.config.erb +++ b/rabbitmq/templates/rabbitmq.config.erb @@ -1,12 +1,15 @@ % This file managed by Puppet % Template Path: <%= @module_name %>/templates/rabbitmq.config [ +<%- if @ssl and @ssl_versions -%> + {ssl, [{versions, [<%= @ssl_versions.sort.map { |v| "'#{v}'" }.join(', ') %>]}]}, +<%- end -%> {rabbit, [ <% if @ldap_auth -%> {auth_backends, [rabbit_auth_backend_internal, rabbit_auth_backend_ldap]}, <% end -%> <% if @config_cluster -%> - {cluster_nodes, {[<%= @r_cluster_nodes.map { |n| "\'rabbit@#{n}\'" }.join(', ') %>], <%= @cluster_node_type %>}}, + {cluster_nodes, {[<%= @cluster_nodes.map { |n| "\'rabbit@#{n}\'" }.join(', ') %>], <%= @cluster_node_type %>}}, {cluster_partition_handling, <%= @cluster_partition_handling %>}, <% end -%> <%- if @tcp_keepalive -%> @@ -17,11 +20,14 @@ <%- end -%> <%- if @ssl -%> {ssl_listeners, [<%= @ssl_port %>]}, - {ssl_options, [{cacertfile,"<%= @ssl_cacert %>"}, + {ssl_options, [<%- if @ssl_cacert != 'UNSET' -%>{cacertfile,"<%= @ssl_cacert %>"},<%- end -%> {certfile,"<%= @ssl_cert %>"}, {keyfile,"<%= @ssl_key %>"}, {verify,<%= @ssl_verify %>}, - {fail_if_no_peer_cert,<%= @ssl_fail_if_no_peer_cert %>}]}, + {fail_if_no_peer_cert,<%= @ssl_fail_if_no_peer_cert %>} + <%- if @ssl_versions -%> + ,{versions, [<%= @ssl_versions.sort.map { |v| "'#{v}'" }.join(', ') %>]} + <% end -%>]}, <%- end -%> <% if @config_variables -%> <%- @config_variables.keys.sort.each do |key| -%> @@ -41,9 +47,12 @@ <%- if @ssl -%> {port, <%= @ssl_management_port %>}, {ssl, true}, - {ssl_opts, [{cacertfile, "<%= @ssl_cacert %>"}, + {ssl_opts, [<%- if @ssl_cacert != 'UNSET' -%>{cacertfile, "<%= @ssl_cacert %>"},<%- end -%> {certfile, "<%= @ssl_cert %>"}, - {keyfile, "<%= @ssl_key %>"}]} + {keyfile, "<%= @ssl_key %>"} + <%- if @ssl_versions -%> + ,{versions, [<%= @ssl_versions.sort.map { |v| "'#{v}'" }.join(', ') %>]} + <% end -%>]} <%- else -%> {port, <%= @management_port %>} <%- end -%> diff --git a/rabbitmq/templates/rabbitmqadmin.conf.erb b/rabbitmq/templates/rabbitmqadmin.conf.erb new file mode 100644 index 000000000..d76c81147 --- /dev/null +++ b/rabbitmq/templates/rabbitmqadmin.conf.erb @@ -0,0 +1,7 @@ +[default] +<% if @ssl -%> +ssl = True +port = <%= @ssl_management_port %> +<% else -%> +port = <%= @management_port %> +<% end -%>