forge "http://forge.puppetlabs.com"
-#mod 'puppetlabs/rabbitmq', '5.1.0'
#mod 'puppetlabs/xinetd', '1.5.0'
#mod 'puppetlabs/stunnel', '0.1.0'
mod 'puppetlabs/stdlib', '4.6.0'
mod 'puppetlabs/concat', '1.2.2'
+mod 'puppetlabs/rabbitmq', '5.2.1'
mod 'elasticsearch/elasticsearch', '0.9.5'
--- /dev/null
+## 2015-05-26 - Version 5.2.1
+###Summary
+This release includes a fix for idempotency between puppet runs, as well as Readme updates
+
+####Features
+- Readme updates
+- Testing updates
+
+####Bugfixes
+- Ensure idempotency between Puppet runs
+
+## 2015-04-28 - Version 5.2.0
+###Summary
+This release adds several new features for expanded configuration, support for SSL Ciphers, several bugfixes, and improved tests.
+
+####Features
+- New parameters to class `rabbitmq`
+ - `ssl_ciphers`
+- New parameters to class `rabbitmq::config`
+ - `interface`
+ - `ssl_interface`
+- New parameters to type `rabbitmq_exchange`
+ - `internal`
+ - `auto_delete`
+ - `durable`
+- Adds syncing with Modulesync
+- Adds support for SSL Ciphers
+- Adds `file_limit` support for RedHat platforms
+
+####Bugfixes
+- Will not create `rabbitmqadmin.conf` if admin is disabled
+- Fixes `check_password`
+- Fix to allow bindings and queues to be created when non-default management port is being used by rabbitmq. (MODULES-1856)
+- `rabbitmq_policy` converts known parameters to integers
+- Updates apt key for full fingerprint compliance.
+- Adds a missing `routing_key` param to rabbitmqadmin absent binding call.
+
+## 2015-03-10 - Version 5.1.0
+###Summary
+This release adds several features for greater flexibility in configuration of rabbitmq, includes a number of bug fixes, and bumps the minimum required version of puppetlabs-stdlib to 3.0.0.
+
+####Changes to defaults
+- The default environment variables in `rabbitmq::config` have been renamed from `RABBITMQ_NODE_PORT` and `RABBITMQ_NODE_IP_ADDRESS` to `NODE_PORT` and `NODE_IP_ADDRESS` (MODULES-1673)
+
+####Features
+- New parameters to class `rabbitmq`
+ - `file_limit`
+ - `interface`
+ - `ldap_other_bind`
+ - `ldap_config_variables`
+ - `ssl_interface`
+ - `ssl_versions`
+ - `rabbitmq_group`
+ - `rabbitmq_home`
+ - `rabbitmq_user`
+- Add `rabbitmq_queue` and `rabbitmq_binding` types
+- Update the providers to be able to retry commands
+
+####Bugfixes
+- Cleans up the formatting for rabbitmq.conf for readability
+- Update tag splitting in the `rabbitmqctl` provider for `rabbitmq_user` to work with comma or space separated tags
+- Do not enforce the source value for the yum provider (MODULES-1631)
+- Fix conditional around `$pin`
+- Remove broken SSL option in rabbitmqadmin.conf (MODULES-1691)
+- Fix issues in `rabbitmq_user` with admin and no tags
+- Fix issues in `rabbitmq_user` with tags not being sorted
+- Fix broken check for existing exchanges in `rabbitmq_exchange`
+
+## 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
+- 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
+- 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
+from Python script
+- Fix location for rabbitmq-plugins for RHEL
+- Remove validation for package_source to allow it to be set to false
+- 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
+### 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
+- erlang_manage was removed. You will need to manage erlang separately. See
+the README for more information on how to configure this.
+
+#### Features
+- Improved SSL support
+- Add LDAP support
+- Add ability to manage RabbitMQ repositories
+- Add ability to manage Erlang kernel configuration options
+- Improved handling of user tags
+- Use nanliu-staging module instead of hardcoded 'curl'
+- Switch to yum or zypper provider instead of rpm
+- Add ability to manage STOMP plugin installation.
+- Allow empty permission fields
+- Convert existing system tests to beaker acceptance tests.
+
+#### 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
+- Deprecated previously unused manage_service variable in favor of
+ service_manage
+- Use correct key for rabbitmq apt::source
+- config_mirrored_queues variable removed
+ - It previously did nothing, will now at least throw a warning if you try to
+ use it
+- Remove unnecessary dependency on Class['rabbitmq::repo::rhel'] in
+ rabbitmq::install
+
+
+## 2013-09-14 - Version 3.1.0
+### 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
+- 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
+- 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
+
+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
+
+- 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
+- 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)
+- Add rabbitmq_exchange provider (using rabbitmqadmin)
+- Add new `rabbitmq` class parameters:
+ - `manage_service`: Boolean to choose if Puppet should manage the service. (For pacemaker/HA setups)
+- Add SuSE support.
+
+#### 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
+
+- remove puppetversion from rabbitmq.config template
+- add cluster support
+- escape resource names in regexp
+
+## 2012-07-31 Jeff McCune <jeff@puppetlabs.com> 2.0.2
+- Re-release 2.0.1 with $EDITOR droppings cleaned up
+
+## 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 <dan@Puppetlabs.com> 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 <jeff@puppetlabs.com> 1.0.4
+- Update module for RabbitMQ 2.4.1 and rabbitmq-plugin-stomp package.
+
+## 2011-03-24 1.0.3
+- Initial release to the forge. Reviewed by Cody. Whitespace is good.
+
+## 2011-03-22 1.0.2
+- Whitespace only fix again... ack '\t' is my friend...
+
+## 2011-03-22 1.0.1
+- Whitespace only fix.
+
+## 2011-03-22 1.0.0
+- Initial Release. Manage the package, file and service.
--- /dev/null
+Checklist (and a short version for the impatient)
+=================================================
+
+ * Commits:
+
+ - Make commits of logical units.
+
+ - Check for unnecessary whitespace with "git diff --check" before
+ committing.
+
+ - Commit using Unix line endings (check the settings around "crlf" in
+ git-config(1)).
+
+ - Do not check in commented out code or unneeded files.
+
+ - The first line of the commit message should be a short
+ description (50 characters is the soft limit, excluding ticket
+ number(s)), and should skip the full stop.
+
+ - Associate the issue in the message. The first line should include
+ the issue number in the form "(#XXXX) Rest of message".
+
+ - The body should provide a meaningful commit message, which:
+
+ - uses the imperative, present tense: "change", not "changed" or
+ "changes".
+
+ - includes motivation for the change, and contrasts its
+ implementation with the previous behavior.
+
+ - Make sure that you have tests for the bug you are fixing, or
+ feature you are adding.
+
+ - Make sure the test suites passes after your commit:
+ `bundle exec rspec spec/acceptance` More information on [testing](#Testing) below
+
+ - When introducing a new feature, make sure it is properly
+ documented in the README.md
+
+ * Submission:
+
+ * Pre-requisites:
+
+ - Make sure you have a [GitHub account](https://github.com/join)
+
+ - [Create a ticket](https://tickets.puppetlabs.com/secure/CreateIssue!default.jspa), or [watch the ticket](https://tickets.puppetlabs.com/browse/) you are patching for.
+
+ * Preferred method:
+
+ - Fork the repository on GitHub.
+
+ - Push your changes to a topic branch in your fork of the
+ repository. (the format ticket/1234-short_description_of_change is
+ usually preferred for this project).
+
+ - Submit a pull request to the repository in the puppetlabs
+ organization.
+
+The long version
+================
+
+ 1. Make separate commits for logically separate changes.
+
+ Please break your commits down into logically consistent units
+ which include new or changed tests relevant to the rest of the
+ change. The goal of doing this is to make the diff easier to
+ read for whoever is reviewing your code. In general, the easier
+ your diff is to read, the more likely someone will be happy to
+ review it and get it into the code base.
+
+ If you are going to refactor a piece of code, please do so as a
+ separate commit from your feature or bug fix changes.
+
+ We also really appreciate changes that include tests to make
+ sure the bug is not re-introduced, and that the feature is not
+ accidentally broken.
+
+ Describe the technical detail of the change(s). If your
+ description starts to get too long, that is a good sign that you
+ probably need to split up your commit into more finely grained
+ pieces.
+
+ Commits which plainly describe the things which help
+ reviewers check the patch and future developers understand the
+ code are much more likely to be merged in with a minimum of
+ bike-shedding or requested changes. Ideally, the commit message
+ would include information, and be in a form suitable for
+ inclusion in the release notes for the version of Puppet that
+ includes them.
+
+ Please also check that you are not introducing any trailing
+ whitespace or other "whitespace errors". You can do this by
+ running "git diff --check" on your changes before you commit.
+
+ 2. Sending your patches
+
+ To submit your changes via a GitHub pull request, we _highly_
+ recommend that you have them on a topic branch, instead of
+ directly on "master".
+ It makes things much easier to keep track of, especially if
+ you decide to work on another thing before your first change
+ is merged in.
+
+ GitHub has some pretty good
+ [general documentation](http://help.github.com/) on using
+ their site. They also have documentation on
+ [creating pull requests](http://help.github.com/send-pull-requests/).
+
+ In general, after pushing your topic branch up to your
+ repository on GitHub, you can switch to the branch in the
+ GitHub UI and click "Pull Request" towards the top of the page
+ in order to open a pull request.
+
+
+ 3. Update the related GitHub issue.
+
+ If there is a GitHub issue associated with the change you
+ submitted, then you should update the ticket to include the
+ location of your branch, along with any other commentary you
+ may wish to make.
+
+Testing
+=======
+
+Getting Started
+---------------
+
+Our puppet modules provide [`Gemfile`](./Gemfile)s which can tell a ruby
+package manager such as [bundler](http://bundler.io/) what Ruby packages,
+or Gems, are required to build, develop, and test this software.
+
+Please make sure you have [bundler installed](http://bundler.io/#getting-started)
+on your system, then use it to install all dependencies needed for this project,
+by running
+
+```shell
+% bundle install
+Fetching gem metadata from https://rubygems.org/........
+Fetching gem metadata from https://rubygems.org/..
+Using rake (10.1.0)
+Using builder (3.2.2)
+-- 8><-- many more --><8 --
+Using rspec-system-puppet (2.2.0)
+Using serverspec (0.6.3)
+Using rspec-system-serverspec (1.0.0)
+Using bundler (1.3.5)
+Your bundle is complete!
+Use `bundle show [gemname]` to see where a bundled gem is installed.
+```
+
+NOTE some systems may require you to run this command with sudo.
+
+If you already have those gems installed, make sure they are up-to-date:
+
+```shell
+% bundle update
+```
+
+With all dependencies in place and up-to-date we can now run the tests:
+
+```shell
+% rake spec
+```
+
+This will execute all the [rspec tests](http://rspec-puppet.com/) tests
+under [spec/defines](./spec/defines), [spec/classes](./spec/classes),
+and so on. rspec tests may have the same kind of dependencies as the
+module they are testing. While the module defines in its [Modulefile](./Modulefile),
+rspec tests define them in [.fixtures.yml](./fixtures.yml).
+
+Some puppet modules also come with [beaker](https://github.com/puppetlabs/beaker)
+tests. These tests spin up a virtual machine under
+[VirtualBox](https://www.virtualbox.org/)) with, controlling it with
+[Vagrant](http://www.vagrantup.com/) to actually simulate scripted test
+scenarios. In order to run these, you will need both of those tools
+installed on your system.
+
+You can run them by issuing the following command
+
+```shell
+% rake spec_clean
+% rspec spec/acceptance
+```
+
+This will now download a pre-fabricated image configured in the [default node-set](./spec/acceptance/nodesets/default.yml),
+install puppet, copy this module and install its dependencies per [spec/spec_helper_acceptance.rb](./spec/spec_helper_acceptance.rb)
+and then run all the tests under [spec/acceptance](./spec/acceptance).
+
+Writing Tests
+-------------
+
+XXX getting started writing tests.
+
+If you have commit access to the repository
+===========================================
+
+Even if you have commit access to the repository, you will still need to
+go through the process above, and have someone else review and merge
+in your changes. The rule is that all changes must be reviewed by a
+developer on the project (that did not write the code) to ensure that
+all changes go through a code review process.
+
+Having someone other than the author of the topic branch recorded as
+performing the merge is the record that they performed the code
+review.
+
+
+Additional Resources
+====================
+
+* [Getting additional help](http://puppetlabs.com/community/get-help)
+
+* [Writing tests](http://projects.puppetlabs.com/projects/puppet/wiki/Development_Writing_Tests)
+
+* [Patchwork](https://patchwork.puppetlabs.com)
+
+* [General GitHub documentation](http://help.github.com/)
+
+* [GitHub pull request documentation](http://help.github.com/send-pull-requests/)
+
--- /dev/null
+source ENV['GEM_SOURCE'] || "https://rubygems.org"
+
+def location_for(place, fake_version = nil)
+ if place =~ /^(git:[^#]*)#(.*)/
+ [fake_version, { :git => $1, :branch => $2, :require => false }].compact
+ elsif place =~ /^file:\/\/(.*)/
+ ['>= 0', { :path => File.expand_path($1), :require => false }]
+ else
+ [place, { :require => false }]
+ end
+end
+
+group :development, :unit_tests do
+ gem 'rspec-core', '3.1.7', :require => false
+ gem 'puppetlabs_spec_helper', :require => false
+ gem 'simplecov', :require => false
+ gem 'puppet_facts', :require => false
+ gem 'json', :require => false
+end
+
+group :system_tests do
+ if beaker_version = ENV['BEAKER_VERSION']
+ gem 'beaker', *location_for(beaker_version)
+ end
+ if beaker_rspec_version = ENV['BEAKER_RSPEC_VERSION']
+ gem 'beaker-rspec', *location_for(beaker_rspec_version)
+ else
+ gem 'beaker-rspec', :require => false
+ end
+ gem 'serverspec', :require => false
+end
+
+
+
+if facterversion = ENV['FACTER_GEM_VERSION']
+ gem 'facter', facterversion, :require => false
+else
+ gem 'facter', :require => false
+end
+
+if puppetversion = ENV['PUPPET_GEM_VERSION']
+ gem 'puppet', puppetversion, :require => false
+else
+ gem 'puppet', :require => false
+end
+
+# vim:ft=ruby
--- /dev/null
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
+
+ APPENDIX: How to apply the Apache License to your work.
+
+ To apply the Apache License to your work, attach the following
+ boilerplate notice, with the fields enclosed by brackets "[]"
+ replaced with your own identifying information. (Don't include
+ the brackets!) The text should be enclosed in the appropriate
+ comment syntax for the file format. We also recommend that a
+ file or class name and description of purpose be included on the
+ same "printed page" as the copyright notice for easier
+ identification within third-party archives.
+
+ Copyright 2013 Puppet Labs
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
--- /dev/null
+#rabbitmq
+
+####Table of Contents
+
+1. [Overview](#overview)
+2. [Module Description - What the module does and why it is useful](#module-description)
+3. [Setup - The basics of getting started with rabbitmq](#setup)
+ * [What rabbitmq affects](#what-rabbitmq-affects)
+ * [Setup requirements](#setup-requirements)
+ * [Beginning with rabbitmq](#beginning-with-rabbitmq)
+4. [Usage - Configuration options and additional functionality](#usage)
+5. [Reference - An under-the-hood peek at what the module is doing and how](#reference)
+5. [Limitations - OS compatibility, etc.](#limitations)
+ * [RedHat module dependencies](#redhat-module-dependecies)
+6. [Development - Guide for contributing to the module](#development)
+
+##Overview
+
+This module manages RabbitMQ (www.rabbitmq.com)
+
+##Module Description
+The rabbitmq module sets up rabbitmq and has a number of providers to manage
+everything from vhosts to exchanges after setup.
+
+This module has been tested against 2.7.1 and is known to not support
+all features against earlier versions.
+
+##Setup
+
+###What rabbitmq affects
+
+* rabbitmq repository files.
+* rabbitmq package.
+* rabbitmq configuration file.
+* rabbitmq service.
+
+###Beginning with rabbitmq
+
+
+```puppet
+include '::rabbitmq'
+```
+
+##Usage
+
+All options and configuration can be done through interacting with the parameters
+on the main rabbitmq class. These are documented below.
+
+##rabbitmq class
+
+To begin with the rabbitmq class controls the installation of rabbitmq. In here
+you can control many parameters relating to the package and service, such as
+disabling puppet support of the service:
+
+```puppet
+class { '::rabbitmq':
+ service_manage => false,
+ port => '5672',
+ delete_guest_user => true,
+}
+```
+
+Or such as offline installation from intranet or local mirrors:
+
+```puppet
+class { '::rabbitmq':
+ key_content => template('openstack/rabbit.pub.key'),
+ package_gpg_key => '/tmp/rabbit.pub.key',
+}
+```
+
+And this one will use external package key source for any (apt/rpm) package provider:
+
+```puppet
+class { '::rabbitmq':
+ package_gpg_key => 'http://www.some_site.some_domain/some_key.pub.key',
+}
+```
+
+### Environment Variables
+To use RabbitMQ Environment Variables, use the parameters `environment_variables` e.g.:
+
+```puppet
+class { 'rabbitmq':
+ port => '5672',
+ environment_variables => {
+ 'NODENAME' => 'node01',
+ 'SERVICENAME' => 'RabbitMQ'
+ }
+}
+```
+
+### Variables Configurable in rabbitmq.config
+To change RabbitMQ Config Variables in rabbitmq.config, use the parameters `config_variables` e.g.:
+
+```puppet
+class { 'rabbitmq':
+ port => '5672',
+ config_variables => {
+ 'hipe_compile' => true,
+ 'frame_max' => 131072,
+ 'log_levels' => "[{connection, info}]"
+ }
+}
+```
+
+To change Erlang Kernel Config Variables in rabbitmq.config, use the parameters
+`config_kernel_variables` e.g.:
+
+```puppet
+class { 'rabbitmq':
+ port => '5672',
+ config_kernel_variables => {
+ 'inet_dist_listen_min' => 9100,
+ 'inet_dist_listen_max' => 9105,
+ }
+}
+```
+
+### Clustering
+To use RabbitMQ clustering facilities, use the rabbitmq parameters
+`config_cluster`, `cluster_nodes`, and `cluster_node_type`, e.g.:
+
+```puppet
+class { 'rabbitmq':
+ config_cluster => true,
+ cluster_nodes => ['rabbit1', 'rabbit2'],
+ cluster_node_type => 'ram',
+ erlang_cookie => 'A_SECRET_COOKIE_STRING',
+ wipe_db_on_cookie_change => true,
+}
+```
+
+##Reference
+
+##Classes
+
+* rabbitmq: Main class for installation and service management.
+* rabbitmq::config: Main class for rabbitmq configuration/management.
+* rabbitmq::install: Handles package installation.
+* 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 rpm repo for Redhat systems.
+
+###Parameters
+
+####`admin_enable`
+
+Boolean, if enabled sets up the management interface/plugin for RabbitMQ.
+
+####`cluster_node_type`
+
+Choose between disk and ram nodes.
+
+####`cluster_nodes`
+
+An array of nodes for clustering.
+
+####`cluster_partition_handling`
+
+Value to set for `cluster_partition_handling` RabbitMQ configuration variable.
+
+####`config`
+
+The file to use as the rabbitmq.config template.
+
+####`config_cluster`
+
+Boolean to enable or disable clustering support.
+
+####`config_kernel_variables`
+
+Hash of Erlang kernel configuration variables to set (see [Variables Configurable in rabbitmq.config](#variables-configurable-in-rabbitmq.config)).
+
+####`config_mirrored_queues`
+
+DEPRECATED
+
+Configuring queue mirroring should be done by setting the according policy for
+the queue. You can read more about it
+[here](http://www.rabbitmq.com/ha.html#genesis)
+
+####`config_path`
+
+The path to write the RabbitMQ configuration file to.
+
+####`config_stomp`
+
+Boolean to enable or disable stomp.
+
+####`config_variables`
+
+To set config variables in rabbitmq.config
+
+####`default_user`
+
+Username to set for the `default_user` in rabbitmq.config.
+
+####`default_pass`
+
+Password to set for the `default_user` in rabbitmq.config.
+
+####`delete_guest_user`
+
+Boolean to decide if we should delete the default guest user.
+
+####`env_config`
+
+The template file to use for rabbitmq_env.config.
+
+####`env_config_path`
+
+The path to write the rabbitmq_env.config file to.
+
+####`environment_variables`
+
+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.
+
+####`file_limit`
+
+Set rabbitmq file ulimit. Defaults to 16384. Only available on systems with
+`$::osfamily == 'Debian'` or `$::osfamily == 'RedHat'`.
+
+####`key_content`
+
+Uses content method for Debian OS family. Should be a template for apt::source
+class. Overrides `package_gpg_key` behavior, if enabled. Undefined by default.
+
+####`ldap_auth`
+
+Boolean, set to true to enable LDAP auth.
+
+####`ldap_server`
+
+LDAP server to use for auth.
+
+####`ldap_user_dn_pattern`
+
+User DN pattern for LDAP auth.
+
+####`ldap_other_bind`
+
+How to bind to the LDAP server. Defaults to 'anon'.
+
+####`ldap_config_variables`
+
+Hash of other LDAP config variables.
+
+####`ldap_use_ssl`
+
+Boolean, set to true to use SSL for the LDAP server.
+
+####`ldap_port`
+
+Numeric port for LDAP server.
+
+####`ldap_log`
+
+Boolean, set to true to log LDAP auth.
+
+####`manage_repos`
+
+Boolean, whether or not to manage package repositories.
+
+####`management_port`
+
+The port for the RabbitMQ management interface.
+
+####`node_ip_address`
+
+The value of NODE_IP_ADDRESS in rabbitmq_env.config
+
+####`package_ensure`
+
+Determines the ensure state of the package. Set to installed by default, but could
+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.
+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.
+
+####`package_name`
+
+The name of the package to install.
+
+####`package_provider`
+
+What provider to use to install the package.
+
+####`package_source`
+
+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.
+
+####`port`
+
+The RabbitMQ port.
+
+####`service_ensure`
+
+The state of the service.
+
+####`service_manage`
+
+Determines if the service is managed.
+
+####`service_name`
+
+The name of the service to manage.
+
+####`ssl`
+
+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 and port => UNSET also
+
+####`ssl_cacert`
+
+CA cert path to use for SSL.
+
+####`ssl_cert`
+
+Cert to use for SSL.
+
+####`ssl_key`
+
+Key to use for SSL.
+
+####`ssl_management_port`
+
+SSL management port.
+
+####`ssl_stomp_port`
+
+SSL stomp port.
+
+####`ssl_verify`
+
+rabbitmq.config SSL verify setting.
+
+####`ssl_fail_if_no_peer_cert`
+
+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.
+
+####`ssl_ciphers`
+
+Support only a given list of SSL ciphers. Example: `['dhe_rsa,aes_256_cbc,sha','dhe_dss,aes_256_cbc,sha','ecdhe_rsa,aes_256_cbc,sha']`.
+
+Supported ciphers in your install can be listed with:
+ rabbitmqctl eval 'ssl:cipher_suites().'
+Functionality can be tested with cipherscan or similar tool: https://github.com/jvehent/cipherscan.git
+
+####`stomp_port`
+
+The port to use for Stomp.
+
+####`stomp_ensure`
+
+Boolean to install the stomp plugin.
+
+####`tcp_keepalive`
+
+Boolean to enable TCP connection keepalive for RabbitMQ service.
+
+####`version`
+
+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.
+
+####`rabbitmq_user`
+
+String: OS dependent, default defined in param.pp. The system user the rabbitmq daemon runs as.
+
+####`rabbitmq_group`
+
+String: OS dependent, default defined in param.pp. The system group the rabbitmq daemon runs as.
+
+####`rabbitmq_home`
+
+String: OS dependent. default defined in param.pp. The home directory of the rabbitmq deamon.
+
+##Native Types
+
+### rabbitmq\_user
+
+query all current users: `$ puppet resource rabbitmq_user`
+
+```
+rabbitmq_user { 'dan':
+ admin => true,
+ password => 'bar',
+}
+```
+Optional parameter tags will set further rabbitmq tags like monitoring, policymaker, etc.
+To set the administrator tag use admin-flag.
+```puppet
+rabbitmq_user { 'dan':
+ admin => true,
+ password => 'bar',
+ tags => ['monitoring', 'tag1'],
+}
+```
+
+
+### rabbitmq\_vhost
+
+query all current vhosts: `$ puppet resource rabbitmq_vhost`
+
+```puppet
+rabbitmq_vhost { 'myvhost':
+ ensure => present,
+}
+```
+
+### rabbitmq\_exchange
+
+```puppet
+rabbitmq_exchange { 'myexchange@myvhost':
+ user => 'dan',
+ password => 'bar',
+ type => 'topic',
+ ensure => present,
+ internal => false,
+ auto_delete => false,
+ durable => true,
+ arguments => {
+ hash-header => 'message-distribution-hash'
+ }
+}
+```
+
+### rabbitmq\_queue
+
+```puppet
+rabbitmq_queue { 'myqueue@myvhost':
+ 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@myvhost':
+ user => 'dan',
+ password => 'bar',
+ destination_type => 'queue',
+ routing_key => '#',
+ arguments => {},
+ ensure => present,
+}
+```
+
+### rabbitmq\_user\_permissions
+
+```puppet
+rabbitmq_user_permissions { 'dan@myvhost':
+ configure_permission => '.*',
+ read_permission => '.*',
+ write_permission => '.*',
+}
+```
+
+### rabbitmq\_policy
+
+```puppet
+rabbitmq_policy { 'ha-all@myvhost':
+ pattern => '.*',
+ priority => 0,
+ applyto => 'all',
+ definition => {
+ 'ha-mode' => 'all',
+ 'ha-sync-mode' => 'automatic',
+ },
+}
+```
+
+### rabbitmq\_plugin
+
+query all currently enabled plugins `$ puppet resource rabbitmq_plugin`
+
+```puppet
+rabbitmq_plugin {'rabbitmq_stomp':
+ ensure => present,
+}
+```
+
+### 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 "${rabbitmq_home}/.erlang.cookie", which includes
+stopping the rabbitmq service and wiping out the database at
+"${rabbitmq_home}/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 3.x.
+
+The module has been tested on:
+
+* RedHat Enterprise Linux 5/6
+* Debian 6/7
+* CentOS 5/6
+* 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:
+
+ puppet module install garethr-erlang
+
+This module handles the packages for erlang.
+To use the module, add the following snippet to your site.pp or an appropriate profile class:
+
+For RedHat systems:
+
+ include 'erlang'
+ class { 'erlang': epel_enable => true}
+
+For Debian systems:
+
+ include 'erlang'
+ package { 'erlang-base':
+ ensure => 'latest',
+ }
+
+This module also depends on the excellent nanliu/staging module on the Forge:
+
+ puppet module install nanliu-staging
+
+### Downgrade Issues
+
+Be advised that there were configuration file syntax and other changes made between RabbitMQ
+versions 2 and 3. In order to downgrade from 3 to 2 (not that this is a terribly good idea)
+you will need to manually remove all RabbitMQ configuration files (``/etc/rabbitmq``) and
+the mnesia directory (usually ``/var/lib/rabbitmq/mnesia``). The latter action will delete
+any and all messages stored to disk.
+
+Failure to do this will result in RabbitMQ failing to start with a cryptic error message about
+"init terminating in do_boot", containing "rabbit_upgrade,maybe_upgrade_mnesia".
+
+##Development
+
+Puppet Labs modules on the Puppet Forge are open projects, and community
+contributions are essential for keeping them great. We can’t access the
+huge number of platforms and myriad of hardware, software, and deployment
+configurations that Puppet is intended to serve.
+
+We want to keep it as easy as possible to contribute changes so that our
+modules work in your environment. There are a few guidelines that we need
+contributors to follow so that we can have a chance of keeping on top of things.
+
+You can read the complete module contribution guide [on the Puppet Labs wiki.](http://projects.puppetlabs.com/projects/module-site/wiki/Module_contributing)
+
+### Authors
+* Jeff McCune <jeff@puppetlabs.com>
+* Dan Bode <dan@puppetlabs.com>
+* RPM/RHEL packages by Vincent Janelle <randomfrequency@gmail.com>
+* Puppetlabs Module Team
--- /dev/null
+require 'puppetlabs_spec_helper/rake_tasks'
+require 'puppet-lint/tasks/puppet-lint'
+
+PuppetLint.configuration.fail_on_warnings = true
+PuppetLint.configuration.send('relative')
+PuppetLint.configuration.send('disable_80chars')
+PuppetLint.configuration.send('disable_class_inherits_from_params_class')
+PuppetLint.configuration.send('disable_documentation')
+PuppetLint.configuration.send('disable_single_quote_string_with_variables')
+PuppetLint.configuration.ignore_paths = ["spec/**/*.pp", "pkg/**/*.pp"]
--- /dev/null
+provider TODO -
+ - password should be a property and not a param
+ - what if we tried to log in as that user?
+ - can permissions from list_user_permissions contain whitespace?
+ - what about defaultfor :true?
+ - prefetching for performance
+ - rabbit plugin should require rabbitmq class
+ - rabbitmq class should be renamed server??
+ - service name should default to -server
+ - cannot find stomp package
--- /dev/null
+{
+ "CHANGELOG.md": "43cb464088dc5a6558ce1f2f119a0f48",
+ "CONTRIBUTING.md": "e2b8e8e433fc76b3798b7fe435f49375",
+ "Gemfile": "e62c96457cdaab2a09f1a37479ea6351",
+ "LICENSE": "6089b6bd1f0d807edb8bdfd76da0b038",
+ "README.md": "1babcf19c9f1f10e3a594b6b89620b49",
+ "Rakefile": "d953eb985f82600dc3b9ac6e1f2cfe64",
+ "TODO": "53cf21155ec1e83e3e167f711fd3ff9f",
+ "files/README.markdown": "3d44458cc68d8513b51e3b56c604eec4",
+ "files/plugins/amqp_client-2.3.1.ez": "543ec53b7208fdc2dc4eba3684868011",
+ "files/plugins/rabbit_stomp-2.3.1.ez": "f552a986409a6d407a080b1aceb80d20",
+ "lib/puppet/provider/rabbitmq_binding/rabbitmqadmin.rb": "1b7bd0bd9ce3e0303f52178487170f42",
+ "lib/puppet/provider/rabbitmq_erlang_cookie/ruby.rb": "80c99bb254471ed32e6ee25a9dcb6f73",
+ "lib/puppet/provider/rabbitmq_exchange/rabbitmqadmin.rb": "f79a7aab47e00a6d29910e09550f03d9",
+ "lib/puppet/provider/rabbitmq_plugin/rabbitmqplugins.rb": "393eac704e7f906052f4d1c285de364e",
+ "lib/puppet/provider/rabbitmq_policy/rabbitmqctl.rb": "ea39ffa45a616fcd755c8121338fcbcd",
+ "lib/puppet/provider/rabbitmq_queue/rabbitmqadmin.rb": "b971f7ec8f5454623d82b35a6c178432",
+ "lib/puppet/provider/rabbitmq_user/rabbitmqctl.rb": "eeddc61ef6c57e7225c818e494fc6e47",
+ "lib/puppet/provider/rabbitmq_user_permissions/rabbitmqctl.rb": "35c1224ef9f1191c61cc577d7b496395",
+ "lib/puppet/provider/rabbitmq_vhost/rabbitmqctl.rb": "3e4754621f03062a4620950134cb2042",
+ "lib/puppet/provider/rabbitmqctl.rb": "59d97156cab9dba9008426e650df17bc",
+ "lib/puppet/type/rabbitmq_binding.rb": "5c19f5f98247d4ee5286e16242a53441",
+ "lib/puppet/type/rabbitmq_erlang_cookie.rb": "ad082a425169634391888fcd9a2131bb",
+ "lib/puppet/type/rabbitmq_exchange.rb": "3ed3e62c8f85cc4e41a81cd07915727c",
+ "lib/puppet/type/rabbitmq_plugin.rb": "6a707d089d0e50a949ecf8fae114eab0",
+ "lib/puppet/type/rabbitmq_policy.rb": "6e421d709978675d36bd6e1e361be498",
+ "lib/puppet/type/rabbitmq_queue.rb": "653a5e3eaa69c6d0d29f477c40362c13",
+ "lib/puppet/type/rabbitmq_user.rb": "4cac856b77ccebff4e9fd63e71ccf611",
+ "lib/puppet/type/rabbitmq_user_permissions.rb": "2d12cd7d9c8bd2afd2e4a4b24a35b58b",
+ "lib/puppet/type/rabbitmq_vhost.rb": "ff6fc35bb9c22b1c493b84adf6bb3167",
+ "log/centos-6-x64-vcloud/2015-05-22_18_55_23/sut.log": "062a9bc8d4ae0dd97e5ee74784a26c9d",
+ "log/centos-6-x64-vcloud/2015-05-22_18_57_07/sut.log": "4b5085af02e0fba4e6ae0addee258ce1",
+ "log/debian-7-x64-vcloud/2015-05-22_18_35_45/sut.log": "b6c8b56197861c0e6c3a46fb730f3334",
+ "log/debian-7-x64-vcloud/2015-05-22_18_49_58/sut.log": "a4d4b5f2278e5cba66026ad9f0156de4",
+ "log/debian-7-x64-vcloud/2015-05-22_19_10_48/sut.log": "27d3e61d3a9d9da3b87501a49f49aece",
+ "log/debian-7-x64-vcloud/2015-05-22_19_11_31/sut.log": "ad6cbb9cbd128e0848c5f5bcfe3d494a",
+ "log/default/2015-05-22_18_35_28/sut.log": "d41d8cd98f00b204e9800998ecf8427e",
+ "manifests/config.pp": "df0d180fd482f63eb8b26ca2ca83febf",
+ "manifests/init.pp": "52b0931a4d2083e90e36c331d6450084",
+ "manifests/install/rabbitmqadmin.pp": "64a81e06996b5ecc147795e64f3c6e7b",
+ "manifests/install.pp": "0f700b158484bfdacb2ce3ec65b939c9",
+ "manifests/management.pp": "93c41d238f2734fa7c5944b8f32f6cc4",
+ "manifests/params.pp": "260d40f1ece0f76e4a86079455e12c87",
+ "manifests/repo/apt.pp": "a5b1a06ac77526e8764bc754bc0718c4",
+ "manifests/repo/rhel.pp": "1c4cfcba993e0667b65ec3c5deafbac7",
+ "manifests/server.pp": "3bc67c2006c1144c50c3fc04394cd800",
+ "manifests/service.pp": "ec365148eec9e739ca06e24c972cd5de",
+ "metadata.json": "cfe09daeacab44586c336f6ea55d6aff",
+ "spec/README.markdown": "32a1fc0121c28aff554ef5d422b8b51e",
+ "spec/acceptance/class_spec.rb": "26e9ed9f9391692419f110624c091390",
+ "spec/acceptance/clustering_spec.rb": "1aa359697551e1ddf2a030cac5b8f2f5",
+ "spec/acceptance/delete_guest_user_spec.rb": "7c5da810cf2a3a124943eb56c46cac83",
+ "spec/acceptance/nodesets/centos-59-x64.yml": "57eb3e471b9042a8ea40978c467f8151",
+ "spec/acceptance/nodesets/centos-6-x64-vcloud.yml": "aaa7352c8a5f5244a6f9008112918074",
+ "spec/acceptance/nodesets/centos-64-x64-pe.yml": "ec075d95760df3d4702abea1ce0a829b",
+ "spec/acceptance/nodesets/centos-65-x64.yml": "3e5c36e6aa5a690229e720f4048bb8af",
+ "spec/acceptance/nodesets/debian-7-x64-vcloud.yml": "83c1c189f46fced0a8d5ec27a3e12877",
+ "spec/acceptance/nodesets/default.yml": "d65958bdf25fb31eb4838fd984b555df",
+ "spec/acceptance/nodesets/ubuntu-server-10044-x64.yml": "75e86400b7889888dc0781c0ae1a1297",
+ "spec/acceptance/nodesets/ubuntu-server-12042-x64.yml": "d30d73e34cd50b043c7d14e305955269",
+ "spec/acceptance/nodesets/ubuntu-server-1404-x64.yml": "5f0aed10098ac5b78e4217bb27c7aaf0",
+ "spec/acceptance/policy_spec.rb": "28211810baf46a25e0e9dda0097ce2db",
+ "spec/acceptance/queue_spec.rb": "b7d54bd218982f191b8a909652d65d09",
+ "spec/acceptance/rabbitmqadmin_spec.rb": "7844ca3109ed35147ee8bcd2c8a045c6",
+ "spec/acceptance/server_spec.rb": "f88e85559c71afcf5d80b01ffd78877d",
+ "spec/acceptance/user_spec.rb": "1f560f25a45e249bafdae3964efabaf2",
+ "spec/acceptance/vhost_spec.rb": "75c867b618eae881b9f13272cffdc777",
+ "spec/acceptance/zz281_spec.rb": "56051cd811c1f2546bcdce2590860306",
+ "spec/classes/rabbitmq_spec.rb": "45725cd9e08e33a4ea809a7ec48ee2f8",
+ "spec/spec.opts": "a600ded995d948e393fbe2320ba8e51c",
+ "spec/spec_helper.rb": "0db89c9a486df193c0e40095422e19dc",
+ "spec/spec_helper_acceptance.rb": "9aa45d83b91ef209b17abeace32781bf",
+ "spec/unit/puppet/provider/rabbitmq_binding/rabbitmqadmin_spec.rb": "f855af3424e3573b37f015f460b3f3f5",
+ "spec/unit/puppet/provider/rabbitmq_exchange/rabbitmqadmin_spec.rb": "3a909fddbe1019b6bf68d43408c5fa70",
+ "spec/unit/puppet/provider/rabbitmq_plugin/rabbitmqctl_spec.rb": "430f9d204f9a0135772b90f10fb36c76",
+ "spec/unit/puppet/provider/rabbitmq_policy/rabbitmqctl_spec.rb": "9b9213cc615b7e164a5b2c754c57f2d0",
+ "spec/unit/puppet/provider/rabbitmq_queue/rabbitmqadmin_spec.rb": "6f7664ce99673b73114ec17afa20febe",
+ "spec/unit/puppet/provider/rabbitmq_user/rabbitmqctl_spec.rb": "b6835fdfed6719217325e36667e9b416",
+ "spec/unit/puppet/provider/rabbitmq_user_permissions/rabbitmqctl_spec.rb": "7a16aee31dbf747d0226ded6ce8a3b45",
+ "spec/unit/puppet/provider/rabbitmq_vhost/rabbitmqctl_spec.rb": "1f8d85c70d5f288a2ac803c99dc3eb72",
+ "spec/unit/puppet/type/rabbitmq_binding_spec.rb": "60bde85ca7075b0584bfd57bd86ebfd3",
+ "spec/unit/puppet/type/rabbitmq_exchange_spec.rb": "797b8a550f0620731efc2280a0f30a53",
+ "spec/unit/puppet/type/rabbitmq_policy_spec.rb": "387079c6a0235602c4ef18b456c2b282",
+ "spec/unit/puppet/type/rabbitmq_queue_spec.rb": "568f66963bd4392b91fe347b3e1baa45",
+ "spec/unit/puppet/type/rabbitmq_user_permissions_spec.rb": "eb5b390edb76be3a2b8899e9b996d6e1",
+ "spec/unit/puppet/type/rabbitmq_user_spec.rb": "80e042c92f64e3a5f97a83bbbde85d42",
+ "spec/unit/puppet/type/rabbitmq_vhost_spec.rb": "162e29065eb5ce664842b66bcfa0ac34",
+ "templates/README.markdown": "aada0a1952329e46b98695349dba6203",
+ "templates/default.erb": "800642a1015e3eaa37f18100d1d63f41",
+ "templates/limits.conf": "c5f991430be0bcb7446eb7291cf34bf8",
+ "templates/rabbitmq-env.conf.erb": "174bf40d6f7fed0cf29604e858cc96c4",
+ "templates/rabbitmq-server.service.d/limits.conf": "80655f98baca4c7bc673359c5f846690",
+ "templates/rabbitmq.config.erb": "1d0ed42cd32aa466b4f3c4d3efb252cb",
+ "templates/rabbitmqadmin.conf.erb": "df2a15c7ee621cced815916cb0c56a5f",
+ "tests/erlang_deps.pp": "4a2ac78d56802dee3a66e3246633b603",
+ "tests/full.pp": "fb1e9f59fe63846c60b402202152eeb0",
+ "tests/permissions/add.pp": "b53b627a4d5521af8cdcfd83d99d3824",
+ "tests/plugin.pp": "5fc1271d5684dd51fa94b67876179e63",
+ "tests/repo/apt.pp": "4ea43b4f8dcaf474ec11d796efef66a3",
+ "tests/server.pp": "56dba93d20d5b716b66df2e0f4f693d6",
+ "tests/service.pp": "f06296b103daf449f9e7644fd9eee58b",
+ "tests/site.pp": "653334bf690768a8af42cd13e8e53ef2",
+ "tests/user/add.pp": "d9f051f1edc91114097b54f818729ea8",
+ "tests/vhosts/add.pp": "f054d84ac87dc206f586d779fc312fa6"
+}
\ No newline at end of file
--- /dev/null
+Files
+=====
+
+Puppet comes with both a client and server for copying files around. The file
+serving function is provided as part of the central Puppet daemon,
+puppetmasterd, and the client function is used through the source attribute of
+file objects. Learn more at
+http://projects.puppetlabs.com/projects/puppet/wiki/File_Serving_Configuration
+
+You can use managed files like this:
+
+ class myclass {
+ package { mypackage: ensure => latest }
+ service { myservice: ensure => running }
+ file { "/etc/myfile":
+ source => "puppet://$servername/modules/mymodule/myfile"
+ }
+ }
+
+The files are searched for in:
+
+ $modulepath/mymodule/files/myfile
--- /dev/null
+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]}",
+ '-c',
+ '/etc/rabbitmq/rabbitmqadmin.conf',
+ "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]}", '-c', '/etc/rabbitmq/rabbitmqadmin.conf', "source=#{name}", "destination_type=#{resource[:destination_type]}", "destination=#{destination}", "properties_key=#{resource[:routing_key]}")
+ @property_hash[:ensure] = :absent
+ end
+
+end
--- /dev/null
+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(resource[:rabbitmq_home] + File::PATH_SEPARATOR + 'mnesia')
+ File.open(resource[:path], 'w') do |cookie|
+ cookie.chmod(0400)
+ cookie.write(value)
+ end
+ FileUtils.chown(resource[:rabbitmq_user], resource[:rabbitmq_group], 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
--- /dev/null
+require 'puppet'
+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'
+ 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('@')[1]
+ end
+ end
+
+ def self.all_vhosts
+ vhosts = []
+ self.run_with_retries {
+ rabbitmqctl('-q', 'list_vhosts')
+ }.split(/\n/).each do |vhost|
+ vhosts.push(vhost)
+ end
+ vhosts
+ end
+
+ def self.all_exchanges(vhost)
+ exchanges = []
+ self.run_with_retries {
+ rabbitmqctl('-q', 'list_exchanges', '-p', vhost, 'name', 'type', 'internal', 'durable', 'auto_delete', 'arguments')
+ }.split(/\n/).each do |exchange|
+ exchanges.push(exchange)
+ end
+ exchanges
+ end
+
+ def self.instances
+ resources = []
+ all_vhosts.each do |vhost|
+ all_exchanges(vhost).each do |line|
+ name, type, internal, durable, auto_delete, arguments = line.split()
+ if type.nil?
+ # if name is empty, it will wrongly get the type's value.
+ # This way type will get the correct value
+ type = name
+ name = ''
+ end
+ # 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
+ exchange = {
+ :type => type,
+ :ensure => :present,
+ :internal => internal,
+ :durable => durable,
+ :auto_delete => auto_delete,
+ :name => "%s@%s" % [name, vhost],
+ :arguments => JSON.parse(arguments),
+ }
+ resources << new(exchange) if exchange[:type]
+ 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('@')[0]
+ arguments = resource[:arguments]
+ if arguments.nil?
+ arguments = {}
+ end
+ rabbitmqadmin('declare', 'exchange', vhost_opt, "--user=#{resource[:user]}", "--password=#{resource[:password]}", "name=#{name}", "type=#{resource[:type]}", "internal=#{resource[:internal]}", "durable=#{resource[:durable]}", "auto_delete=#{resource[:auto_delete]}", "arguments=#{arguments.to_json}", '-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}", '-c', '/etc/rabbitmq/rabbitmqadmin.conf')
+ @property_hash[:ensure] = :absent
+ end
+
+end
--- /dev/null
+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'
+ commands :rabbitmqplugins => '/usr/lib/rabbitmq/bin/rabbitmq-plugins'
+ else
+ commands :rabbitmqplugins => 'rabbitmq-plugins'
+ end
+ else
+ if Facter.value(:osfamily) == 'RedHat'
+ has_command(:rabbitmqplugins, '/usr/lib/rabbitmq/bin/rabbitmq-plugins') do
+ environment :HOME => "/tmp"
+ end
+ else
+ has_command(:rabbitmqplugins, 'rabbitmq-plugins') do
+ environment :HOME => "/tmp"
+ end
+ end
+ end
+
+ defaultfor :feature => :posix
+
+ def self.instances
+ 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}"
+ end
+ end
+ end
+
+ def create
+ rabbitmqplugins('enable', resource[:name])
+ end
+
+ def destroy
+ rabbitmqplugins('disable', resource[:name])
+ end
+
+ def exists?
+ self.class.run_with_retries {
+ rabbitmqplugins('list', '-E', '-m')
+ }.split(/\n/).detect do |line|
+ line.match(/^#{resource[:name]}$/)
+ end
+ end
+
+end
--- /dev/null
+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
--- /dev/null
+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]}",
+ '-c',
+ '/etc/rabbitmq/rabbitmqadmin.conf',
+ "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]}", '-c', '/etc/rabbitmq/rabbitmqadmin.conf', "name=#{name}")
+ @property_hash[:ensure] = :absent
+ end
+
+end
--- /dev/null
+require 'puppet'
+require 'set'
+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'
+ else
+ has_command(:rabbitmqctl, 'rabbitmqctl') do
+ environment :HOME => "/tmp"
+ end
+ end
+
+ defaultfor :feature => :posix
+
+ def self.instances
+ self.run_with_retries {
+ rabbitmqctl('-q', 'list_users')
+ }.split(/\n/).collect do |line|
+ if line =~ /^(\S+)(\s+\[.*?\]|)$/
+ new(:name => $1)
+ else
+ raise Puppet::Error, "Cannot parse invalid user line: #{line}"
+ end
+ end
+ end
+
+ def create
+ rabbitmqctl('add_user', resource[:name], resource[:password])
+ if resource[:admin] == :true
+ make_user_admin()
+ end
+ if ! resource[:tags].empty?
+ set_user_tags(resource[:tags])
+ end
+ end
+
+ def change_password
+ rabbitmqctl('change_password', resource[:name], resource[:password])
+ end
+
+ def password
+ nil
+ end
+
+
+ def check_password
+ response = rabbitmqctl('eval', 'rabbit_access_control:check_user_pass_login(list_to_binary("' + resource[:name] + '"), list_to_binary("' + resource[:password] +'")).')
+ if response.include? 'refused'
+ false
+ else
+ true
+ end
+ end
+
+ def destroy
+ rabbitmqctl('delete_user', resource[:name])
+ end
+
+ def exists?
+ 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
+ tags = get_user_tags
+ # do not expose the administrator tag for admins
+ if resource[:admin] == :true
+ tags.delete('administrator')
+ end
+ tags.entries.sort
+ end
+
+
+ def tags=(tags)
+ if ! tags.nil?
+ set_user_tags(tags)
+ end
+ end
+
+ def admin
+ if usertags = get_user_tags
+ (:true if usertags.include?('administrator')) || :false
+ else
+ raise Puppet::Error, "Could not match line '#{resource[:name]} (true|false)' from list_users (perhaps you are running on an older version of rabbitmq that does not support admin users?)"
+ end
+ end
+
+ def admin=(state)
+ if state == :true
+ make_user_admin()
+ else
+ usertags = get_user_tags
+ usertags.delete('administrator')
+ rabbitmqctl('set_user_tags', resource[:name], usertags.entries.sort)
+ end
+ end
+
+ def set_user_tags(tags)
+ is_admin = get_user_tags().member?("administrator") \
+ || resource[:admin] == :true
+ usertags = Set.new(tags)
+ if is_admin
+ usertags.add("administrator")
+ end
+ rabbitmqctl('set_user_tags', resource[:name], usertags.entries.sort)
+ end
+
+ def make_user_admin
+ usertags = get_user_tags
+ usertags.add('administrator')
+ rabbitmqctl('set_user_tags', resource[:name], usertags.entries.sort)
+ end
+
+ private
+ def get_user_tags
+ 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(' ').map{|x| x.gsub(/,$/, '')}) if match
+ end
+end
--- /dev/null
+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'
+ else
+ has_command(:rabbitmqctl, 'rabbitmqctl') do
+ environment :HOME => "/tmp"
+ end
+ end
+
+ defaultfor :feature=> :posix
+
+ # cache users permissions
+ def self.users(name, vhost)
+ @users = {} unless @users
+ unless @users[name]
+ @users[name] = {}
+ 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}
+ else
+ raise Puppet::Error, "cannot parse line from list_user_permissions:#{line}"
+ end
+ end
+ end
+ @users[name][vhost]
+ end
+
+ def users(name, vhost)
+ self.class.users(name, vhost)
+ end
+
+ def should_user
+ if @should_user
+ @should_user
+ else
+ @should_user = resource[:name].split('@')[0]
+ end
+ end
+
+ def should_vhost
+ if @should_vhost
+ @should_vhost
+ else
+ @should_vhost = resource[:name].split('@')[1]
+ end
+ end
+
+ 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])
+ end
+
+ def destroy
+ rabbitmqctl('clear_permissions', '-p', should_vhost, should_user)
+ end
+
+ # I am implementing prefetching in exists b/c I need to be sure
+ # that the rabbitmq package is installed before I make this call.
+ def exists?
+ users(should_user, should_vhost)
+ end
+
+ def configure_permission
+ users(should_user, should_vhost)[:configure]
+ end
+
+ def configure_permission=(perm)
+ set_permissions
+ end
+
+ def read_permission
+ users(should_user, should_vhost)[:read]
+ end
+
+ def read_permission=(perm)
+ set_permissions
+ end
+
+ def write_permission
+ users(should_user, should_vhost)[:write]
+ end
+
+ def write_permission=(perm)
+ set_permissions
+ end
+
+ # implement memoization so that we only call set_permissions once
+ def set_permissions
+ unless @permissions_set
+ @permissions_set = true
+ resource[:configure_permission] ||= configure_permission
+ resource[:read_permission] ||= read_permission
+ resource[:write_permission] ||= write_permission
+ rabbitmqctl('set_permissions', '-p', should_vhost, should_user,
+ resource[:configure_permission], resource[:write_permission],
+ resource[:read_permission]
+ )
+ 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
--- /dev/null
+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'
+ else
+ has_command(:rabbitmqctl, 'rabbitmqctl') do
+ environment :HOME => "/tmp"
+ end
+ end
+
+ def self.instances
+ self.run_with_retries {
+ rabbitmqctl('-q', 'list_vhosts')
+ }.split(/\n/).map do |line|
+ if line =~ /^(\S+)$/
+ new(:name => $1)
+ else
+ raise Puppet::Error, "Cannot parse invalid user line: #{line}"
+ end
+ end
+ end
+
+ def create
+ rabbitmqctl('add_vhost', resource[:name])
+ end
+
+ def destroy
+ rabbitmqctl('delete_vhost', resource[:name])
+ end
+
+ def exists?
+ out = self.class.run_with_retries {
+ rabbitmqctl('-q', 'list_vhosts')
+ }.split(/\n/).detect do |line|
+ line.match(/^#{Regexp.escape(resource[:name])}$/)
+ end
+ end
+
+end
--- /dev/null
+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
--- /dev/null
+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
--- /dev/null
+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(:rabbitmq_user) do
+ defaultto('rabbitmq')
+ end
+
+ newparam(:rabbitmq_group) do
+ defaultto('rabbitmq')
+ end
+
+ newparam(:rabbitmq_home) do
+ defaultto('/var/lib/rabbitmq')
+ end
+
+ newparam(:service_name) do
+ newvalues(/^\S+$/)
+ end
+end
--- /dev/null
+Puppet::Type.newtype(:rabbitmq_exchange) do
+ desc 'Native type for managing rabbitmq exchanges'
+
+ 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 exchange'
+ newvalues(/^\S*@\S+$/)
+ end
+
+ newparam(:type) do
+ desc 'Exchange type to be set *on creation*'
+ newvalues(/^\S+$/)
+ end
+
+ newparam(:durable) do
+ desc 'Exchange durability to be set *on creation*'
+ newvalues(/^\S+$/)
+ end
+
+ newparam(:auto_delete) do
+ desc 'Exchange auto delete option to be set *on creation*'
+ newvalues(/^\S+$/)
+ end
+
+ newparam(:internal) do
+ desc 'Exchange internal option to be set *on creation*'
+ newvalues(/^\S+$/)
+ end
+
+ newparam(:arguments) do
+ desc 'Exchange arguments example: {"hash-header": "message-distribution-hash"}'
+ defaultto {}
+ 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
+
+ validate do
+ if self[:ensure] == :present and self[:type].nil?
+ raise ArgumentError, "must set type when creating exchange for #{self[:name]} whose type is #{self[:type]}"
+ end
+ 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
+
+end
--- /dev/null
+Puppet::Type.newtype(:rabbitmq_plugin) do
+ desc 'manages rabbitmq plugins'
+
+ ensurable do
+ defaultto(:present)
+ newvalue(:present) do
+ provider.create
+ end
+ newvalue(:absent) do
+ provider.destroy
+ end
+ end
+
+ newparam(:name, :namevar => true) do
+ 'name of the plugin to enable'
+ newvalues(/^\S+$/)
+ end
+
+end
--- /dev/null
+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
+ munge do |value|
+ resource.munge_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
+ if definition['ha-mode'] == 'exactly'
+ ha_params = definition['ha-params']
+ unless ha_params.to_i.to_s == ha_params
+ raise ArgumentError, "Invalid ha-params '#{ha_params}' for ha-mode 'exactly'"
+ end
+ end
+ if definition.key? 'expires'
+ expires_val = definition['expires']
+ unless expires_val.to_i.to_s == expires_val
+ raise ArgumentError, "Invalid expires value '#{expires_val}'"
+ end
+ end
+ end
+
+ def munge_definition(definition)
+ if definition['ha-mode'] == 'exactly'
+ definition['ha-params'] = definition['ha-params'].to_i
+ end
+ if definition.key? 'expires'
+ definition['expires'] = definition['expires'].to_i
+ end
+ definition
+ end
+end
--- /dev/null
+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
--- /dev/null
+Puppet::Type.newtype(:rabbitmq_user) do
+ desc 'Native type for managing rabbitmq users'
+
+ ensurable do
+ defaultto(:present)
+ newvalue(:present) do
+ provider.create
+ end
+ newvalue(:absent) do
+ provider.destroy
+ end
+ end
+
+ autorequire(:service) { 'rabbitmq-server' }
+
+ newparam(:name, :namevar => true) do
+ desc 'Name of user'
+ newvalues(/^\S+$/)
+ end
+
+ 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
+ desc 'whether or not user should be an admin'
+ newvalues(/true|false/)
+ munge do |value|
+ # converting to_s in case its a boolean
+ value.to_s.to_sym
+ end
+ defaultto :false
+ end
+
+ newproperty(:tags, :array_matching => :all) do
+ desc 'additional tags for the user'
+ validate do |value|
+ unless value =~ /^\S+$/
+ raise ArgumentError, "Invalid tag: #{value.inspect}"
+ end
+
+ if value == "administrator"
+ raise ArgumentError, "must use admin property instead of administrator tag"
+ end
+ end
+ defaultto []
+
+ def insync?(is)
+ self.is_to_s(is) == self.should_to_s
+ end
+
+ def is_to_s(currentvalue = @is)
+ if currentvalue
+ "[#{currentvalue.sort.join(', ')}]"
+ else
+ '[]'
+ end
+ end
+
+ def should_to_s(newvalue = @should)
+ if newvalue
+ "[#{newvalue.sort.join(', ')}]"
+ else
+ '[]'
+ end
+ end
+
+ end
+
+ validate do
+ if self[:ensure] == :present and ! self[:password]
+ raise ArgumentError, 'must set password when creating user' unless self[:password]
+ end
+ end
+
+end
--- /dev/null
+Puppet::Type.newtype(:rabbitmq_user_permissions) do
+ desc 'Type for managing rabbitmq user permissions'
+
+ ensurable do
+ defaultto(:present)
+ newvalue(:present) do
+ provider.create
+ end
+ newvalue(:absent) do
+ provider.destroy
+ end
+ end
+
+ autorequire(:service) { 'rabbitmq-server' }
+
+ newparam(:name, :namevar => true) do
+ desc 'combination of user@vhost to grant privileges to'
+ newvalues(/^\S+@\S+$/)
+ end
+
+ newproperty(:configure_permission) do
+ desc 'regexp representing configuration permissions'
+ validate do |value|
+ resource.validate_permissions(value)
+ end
+ end
+
+ newproperty(:read_permission) do
+ desc 'regexp representing read permissions'
+ validate do |value|
+ resource.validate_permissions(value)
+ end
+ end
+
+ newproperty(:write_permission) do
+ desc 'regexp representing write permissions'
+ validate do |value|
+ resource.validate_permissions(value)
+ end
+ end
+
+ autorequire(:rabbitmq_vhost) do
+ [self[:name].split('@')[1]]
+ end
+
+ autorequire(:rabbitmq_user) do
+ [self[:name].split('@')[0]]
+ end
+
+ # I may want to dissalow whitespace
+ def validate_permissions(value)
+ begin
+ Regexp.new(value)
+ rescue RegexpError
+ raise ArgumentError, "Invalid regexp #{value}"
+ end
+ end
+
+end
--- /dev/null
+Puppet::Type.newtype(:rabbitmq_vhost) do
+ desc 'manages rabbitmq vhosts'
+
+ ensurable do
+ defaultto(:present)
+ newvalue(:present) do
+ provider.create
+ end
+ newvalue(:absent) do
+ provider.destroy
+ end
+ end
+
+ autorequire(:service) { 'rabbitmq-server' }
+
+ newparam(:name, :namevar => true) do
+ 'name of the vhost to add'
+ newvalues(/^\S+$/)
+ end
+
+end
--- /dev/null
+2015-05-22 18:55:24 [+] vcloud el-6-x86_64 x7igdqecc5wczwg.delivery.puppetlabs.net (centos-6-vcloud)
+2015-05-22 18:56:27 [-] vcloud el-6-x86_64 x7igdqecc5wczwg.delivery.puppetlabs.net (centos-6-vcloud)
--- /dev/null
+2015-05-22 18:57:08 [+] vcloud el-6-x86_64 bnzq0zsilo3bhbv.delivery.puppetlabs.net (centos-6-vcloud)
+2015-05-22 19:09:48 [-] vcloud el-6-x86_64 bnzq0zsilo3bhbv.delivery.puppetlabs.net (centos-6-vcloud)
--- /dev/null
+2015-05-22 18:35:46 [+] vcloud debian-7-x86_64 upzah8fcy4az78n.delivery.puppetlabs.net (debian-7-vcloud)
+2015-05-22 18:46:28 [-] vcloud debian-7-x86_64 upzah8fcy4az78n.delivery.puppetlabs.net (debian-7-vcloud)
--- /dev/null
+2015-05-22 18:49:59 [+] vcloud debian-7-x86_64 pwvlrfgqbbgoc21.delivery.puppetlabs.net (debian-7-vcloud)
+2015-05-22 18:54:13 [-] vcloud debian-7-x86_64 pwvlrfgqbbgoc21.delivery.puppetlabs.net (debian-7-vcloud)
--- /dev/null
+2015-05-22 19:10:49 [+] vcloud debian-7-x86_64 tnx0tmyf2ws118o.delivery.puppetlabs.net (debian-7-vcloud)
+2015-05-22 19:11:16 [-] vcloud debian-7-x86_64 tnx0tmyf2ws118o.delivery.puppetlabs.net (debian-7-vcloud)
--- /dev/null
+2015-05-22 19:11:32 [+] vcloud debian-7-x86_64 inmrclcv6poi3ho.delivery.puppetlabs.net (debian-7-vcloud)
+2015-05-22 19:15:48 [-] vcloud debian-7-x86_64 inmrclcv6poi3ho.delivery.puppetlabs.net (debian-7-vcloud)
--- /dev/null
+# 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_node_type = $rabbitmq::cluster_node_type
+ $cluster_nodes = $rabbitmq::cluster_nodes
+ $config = $rabbitmq::config
+ $config_cluster = $rabbitmq::config_cluster
+ $config_path = $rabbitmq::config_path
+ $config_stomp = $rabbitmq::config_stomp
+ $default_user = $rabbitmq::default_user
+ $default_pass = $rabbitmq::default_pass
+ $env_config = $rabbitmq::env_config
+ $env_config_path = $rabbitmq::env_config_path
+ $erlang_cookie = $rabbitmq::erlang_cookie
+ $interface = $rabbitmq::interface
+ $management_port = $rabbitmq::management_port
+ $node_ip_address = $rabbitmq::node_ip_address
+ $plugin_dir = $rabbitmq::plugin_dir
+ $rabbitmq_user = $rabbitmq::rabbitmq_user
+ $rabbitmq_group = $rabbitmq::rabbitmq_group
+ $rabbitmq_home = $rabbitmq::rabbitmq_home
+ $port = $rabbitmq::port
+ $tcp_keepalive = $rabbitmq::tcp_keepalive
+ $service_name = $rabbitmq::service_name
+ $ssl = $rabbitmq::ssl
+ $ssl_only = $rabbitmq::ssl_only
+ $ssl_cacert = $rabbitmq::ssl_cacert
+ $ssl_cert = $rabbitmq::ssl_cert
+ $ssl_key = $rabbitmq::ssl_key
+ $ssl_port = $rabbitmq::ssl_port
+ $ssl_interface = $rabbitmq::ssl_interface
+ $ssl_management_port = $rabbitmq::ssl_management_port
+ $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
+ $ssl_ciphers = $rabbitmq::ssl_ciphers
+ $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_other_bind = $rabbitmq::ldap_other_bind
+ $ldap_use_ssl = $rabbitmq::ldap_use_ssl
+ $ldap_port = $rabbitmq::ldap_port
+ $ldap_log = $rabbitmq::ldap_log
+ $ldap_config_variables = $rabbitmq::ldap_config_variables
+ $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
+ $file_limit = $rabbitmq::file_limit
+ $default_env_variables = {
+ 'NODE_PORT' => $port,
+ 'NODE_IP_ADDRESS' => $node_ip_address
+ }
+
+ # Handle env variables.
+ $environment_variables = merge($default_env_variables, $rabbitmq::environment_variables)
+
+ file { '/etc/rabbitmq':
+ ensure => directory,
+ owner => '0',
+ group => '0',
+ mode => '0644',
+ }
+
+ file { '/etc/rabbitmq/ssl':
+ ensure => directory,
+ owner => '0',
+ group => '0',
+ mode => '0644',
+ }
+
+ file { 'rabbitmq.config':
+ ensure => file,
+ path => $config_path,
+ content => template($config),
+ owner => '0',
+ group => '0',
+ mode => '0644',
+ notify => Class['rabbitmq::service'],
+ }
+
+ file { 'rabbitmq-env.config':
+ ensure => file,
+ path => $env_config_path,
+ content => template($env_config),
+ owner => '0',
+ group => '0',
+ mode => '0644',
+ notify => Class['rabbitmq::service'],
+ }
+
+ if $admin_enable {
+ 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'],
+ }
+ }
+
+ case $::osfamily {
+ 'Debian': {
+ file { '/etc/default/rabbitmq-server':
+ ensure => file,
+ content => template('rabbitmq/default.erb'),
+ mode => '0644',
+ owner => '0',
+ group => '0',
+ notify => Class['rabbitmq::service'],
+ }
+ }
+ 'RedHat': {
+ if versioncmp($::operatingsystemmajrelease, '7') >= 0 {
+ file { '/etc/systemd/system/rabbitmq-server.service.d':
+ ensure => directory,
+ owner => '0',
+ group => '0',
+ mode => '0755',
+ selinux_ignore_defaults => true,
+ } ->
+ file { '/etc/systemd/system/rabbitmq-server.service.d/limits.conf':
+ content => template('rabbitmq/rabbitmq-server.service.d/limits.conf'),
+ owner => '0',
+ group => '0',
+ mode => '0644',
+ notify => Exec['rabbitmq-systemd-reload'],
+ }
+ exec { 'rabbitmq-systemd-reload':
+ command => '/usr/bin/systemctl daemon-reload',
+ notify => Class['Rabbitmq::Service'],
+ refreshonly => true,
+ }
+ } else {
+ file { '/etc/security/limits.d/rabbitmq-server.conf':
+ content => template('rabbitmq/limits.conf'),
+ owner => '0',
+ group => '0',
+ mode => '0644',
+ notify => Class['Rabbitmq::Service'],
+ }
+ }
+ }
+ default: {
+ }
+ }
+
+ if $config_cluster {
+
+ if $erlang_cookie == undef {
+ fail('You must set the $erlang_cookie value in order to configure clustering.')
+ } else {
+ rabbitmq_erlang_cookie { "${rabbitmq_home}/.erlang.cookie":
+ content => $erlang_cookie,
+ force => $wipe_db_on_cookie_change,
+ rabbitmq_user => $rabbitmq_user,
+ rabbitmq_group => $rabbitmq_group,
+ rabbitmq_home => $rabbitmq_home,
+ service_name => $service_name,
+ before => File['rabbitmq.config'],
+ notify => Class['rabbitmq::service'],
+ }
+ }
+ }
+}
--- /dev/null
+# Main rabbitmq class
+class rabbitmq(
+ $admin_enable = $rabbitmq::params::admin_enable,
+ $cluster_node_type = $rabbitmq::params::cluster_node_type,
+ $cluster_nodes = $rabbitmq::params::cluster_nodes,
+ $config = $rabbitmq::params::config,
+ $config_cluster = $rabbitmq::params::config_cluster,
+ $config_path = $rabbitmq::params::config_path,
+ $config_stomp = $rabbitmq::params::config_stomp,
+ $default_user = $rabbitmq::params::default_user,
+ $default_pass = $rabbitmq::params::default_pass,
+ $delete_guest_user = $rabbitmq::params::delete_guest_user,
+ $env_config = $rabbitmq::params::env_config,
+ $env_config_path = $rabbitmq::params::env_config_path,
+ $erlang_cookie = $rabbitmq::params::erlang_cookie,
+ $interface = $rabbitmq::params::interface,
+ $management_port = $rabbitmq::params::management_port,
+ $node_ip_address = $rabbitmq::params::node_ip_address,
+ $package_apt_pin = $rabbitmq::params::package_apt_pin,
+ $package_ensure = $rabbitmq::params::package_ensure,
+ $package_gpg_key = $rabbitmq::params::package_gpg_key,
+ $package_name = $rabbitmq::params::package_name,
+ $package_provider = $rabbitmq::params::package_provider,
+ $package_source = undef,
+ $repos_ensure = $rabbitmq::params::repos_ensure,
+ $manage_repos = $rabbitmq::params::manage_repos,
+ $plugin_dir = $rabbitmq::params::plugin_dir,
+ $rabbitmq_user = $rabbitmq::params::rabbitmq_user,
+ $rabbitmq_group = $rabbitmq::params::rabbitmq_group,
+ $rabbitmq_home = $rabbitmq::params::rabbitmq_home,
+ $port = $rabbitmq::params::port,
+ $tcp_keepalive = $rabbitmq::params::tcp_keepalive,
+ $service_ensure = $rabbitmq::params::service_ensure,
+ $service_manage = $rabbitmq::params::service_manage,
+ $service_name = $rabbitmq::params::service_name,
+ $ssl = $rabbitmq::params::ssl,
+ $ssl_only = $rabbitmq::params::ssl_only,
+ $ssl_cacert = $rabbitmq::params::ssl_cacert,
+ $ssl_cert = $rabbitmq::params::ssl_cert,
+ $ssl_key = $rabbitmq::params::ssl_key,
+ $ssl_port = $rabbitmq::params::ssl_port,
+ $ssl_interface = $rabbitmq::params::ssl_interface,
+ $ssl_management_port = $rabbitmq::params::ssl_management_port,
+ $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,
+ $ssl_ciphers = $rabbitmq::params::ssl_ciphers,
+ $stomp_ensure = $rabbitmq::params::stomp_ensure,
+ $ldap_auth = $rabbitmq::params::ldap_auth,
+ $ldap_server = $rabbitmq::params::ldap_server,
+ $ldap_user_dn_pattern = $rabbitmq::params::ldap_user_dn_pattern,
+ $ldap_other_bind = $rabbitmq::params::ldap_other_bind,
+ $ldap_use_ssl = $rabbitmq::params::ldap_use_ssl,
+ $ldap_port = $rabbitmq::params::ldap_port,
+ $ldap_log = $rabbitmq::params::ldap_log,
+ $ldap_config_variables = $rabbitmq::params::ldap_config_variables,
+ $stomp_port = $rabbitmq::params::stomp_port,
+ $version = $rabbitmq::params::version,
+ $wipe_db_on_cookie_change = $rabbitmq::params::wipe_db_on_cookie_change,
+ $cluster_partition_handling = $rabbitmq::params::cluster_partition_handling,
+ $file_limit = $rabbitmq::params::file_limit,
+ $environment_variables = $rabbitmq::params::environment_variables,
+ $config_variables = $rabbitmq::params::config_variables,
+ $config_kernel_variables = $rabbitmq::params::config_kernel_variables,
+ $key_content = undef,
+) inherits rabbitmq::params {
+
+ validate_bool($admin_enable)
+ # Validate install parameters.
+ validate_re($package_apt_pin, '^(|\d+)$')
+ validate_string($package_ensure)
+ validate_string($package_gpg_key)
+ validate_string($package_name)
+ validate_string($package_provider)
+ validate_bool($repos_ensure)
+ validate_re($version, '^\d+\.\d+\.\d+(-\d+)*$') # Allow 3 digits and optional -n postfix.
+ # Validate config parameters.
+ 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)
+ validate_bool($config_cluster)
+ validate_bool($config_stomp)
+ validate_string($default_user)
+ validate_string($default_pass)
+ validate_bool($delete_guest_user)
+ validate_string($env_config)
+ validate_absolute_path($env_config_path)
+ validate_string($erlang_cookie)
+ if ! is_integer($management_port) {
+ validate_re($management_port, '\d+')
+ }
+ validate_string($node_ip_address)
+ validate_absolute_path($plugin_dir)
+ if ! is_integer($port) {
+ validate_re($port, ['\d+','UNSET'])
+ }
+ if ! is_integer($stomp_port) {
+ validate_re($stomp_port, '\d+')
+ }
+ validate_bool($wipe_db_on_cookie_change)
+ validate_bool($tcp_keepalive)
+ if ! is_integer($file_limit) {
+ validate_re($file_limit, '^(unlimited|infinity)$', '$file_limit must be an integer, \'unlimited\', or \'infinity\'.')
+ }
+ # Validate service parameters.
+ validate_re($service_ensure, '^(running|stopped)$')
+ validate_bool($service_manage)
+ validate_string($service_name)
+ validate_bool($ssl)
+ validate_bool($ssl_only)
+ validate_string($ssl_cacert)
+ validate_string($ssl_cert)
+ validate_string($ssl_key)
+ validate_array($ssl_ciphers)
+ if ! is_integer($ssl_port) {
+ validate_re($ssl_port, '\d+')
+ }
+ if ! is_integer($ssl_management_port) {
+ validate_re($ssl_management_port, '\d+')
+ }
+ if ! is_integer($ssl_stomp_port) {
+ validate_re($ssl_stomp_port, '\d+')
+ }
+ validate_bool($stomp_ensure)
+ validate_bool($ldap_auth)
+ validate_string($ldap_server)
+ validate_string($ldap_user_dn_pattern)
+ validate_string($ldap_other_bind)
+ validate_hash($ldap_config_variables)
+ validate_bool($ldap_use_ssl)
+ validate_re($ldap_port, '\d+')
+ validate_bool($ldap_log)
+ validate_hash($environment_variables)
+ validate_hash($config_variables)
+ validate_hash($config_kernel_variables)
+
+ if $ssl_only and ! $ssl {
+ fail('$ssl_only => true requires that $ssl => true')
+ }
+
+ if $config_stomp and $ssl_stomp_port and ! $ssl {
+ 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 $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' }
+ 'Debian': {
+ class { '::rabbitmq::repo::apt' :
+ key_source => $package_gpg_key,
+ key_content => $key_content,
+ }
+ }
+ default:
+ { }
+ }
+ }
+
+ if $admin_enable and $service_manage {
+ include '::rabbitmq::install::rabbitmqadmin'
+
+ rabbitmq_plugin { 'rabbitmq_management':
+ ensure => present,
+ require => Class['rabbitmq::install'],
+ notify => Class['rabbitmq::service'],
+ }
+
+ Class['::rabbitmq::service'] -> Class['::rabbitmq::install::rabbitmqadmin']
+ Class['::rabbitmq::install::rabbitmqadmin'] -> Rabbitmq_exchange<| |>
+ }
+
+ if $stomp_ensure {
+ rabbitmq_plugin { 'rabbitmq_stomp':
+ ensure => present,
+ require => Class['rabbitmq::install'],
+ notify => Class['rabbitmq::service'],
+ }
+ }
+
+ if ($ldap_auth) {
+ rabbitmq_plugin { 'rabbitmq_auth_backend_ldap':
+ ensure => present,
+ require => Class['rabbitmq::install'],
+ notify => Class['rabbitmq::service'],
+ }
+ }
+
+ anchor { 'rabbitmq::begin': }
+ anchor { 'rabbitmq::end': }
+
+ Anchor['rabbitmq::begin'] -> Class['::rabbitmq::install']
+ -> Class['::rabbitmq::config'] ~> Class['::rabbitmq::service']
+ -> Class['::rabbitmq::management'] -> Anchor['rabbitmq::end']
+
+ # Make sure the various providers have their requirements in place.
+ Class['::rabbitmq::install'] -> Rabbitmq_plugin<| |>
+
+}
--- /dev/null
+# 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::real_package_source
+
+ package { 'rabbitmq-server':
+ ensure => $package_ensure,
+ name => $package_name,
+ provider => $package_provider,
+ notify => Class['rabbitmq::service'],
+ }
+
+ if $package_source {
+ Package['rabbitmq-server'] {
+ source => $package_source,
+ }
+ }
+
+}
--- /dev/null
+#
+class rabbitmq::install::rabbitmqadmin {
+
+ 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 => "${rabbitmq::rabbitmq_home}/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']
+ ],
+ }
+
+ file { '/usr/local/bin/rabbitmqadmin':
+ owner => 'root',
+ group => '0',
+ source => "${rabbitmq::rabbitmq_home}/rabbitmqadmin",
+ mode => '0755',
+ require => Staging::File['rabbitmqadmin'],
+ }
+
+}
--- /dev/null
+#
+class rabbitmq::management {
+
+ $delete_guest_user = $rabbitmq::delete_guest_user
+
+ if $delete_guest_user {
+ rabbitmq_user{ 'guest':
+ ensure => absent,
+ provider => 'rabbitmqctl',
+ }
+ }
+
+}
--- /dev/null
+ # Class: rabbitmq::params
+#
+# The RabbitMQ Module configuration settings.
+#
+class rabbitmq::params {
+
+ case $::osfamily {
+ 'Archlinux': {
+ $package_ensure = 'installed'
+ $package_name = 'rabbitmq'
+ $service_name = 'rabbitmq'
+ $version = '3.1.3-1'
+ $rabbitmq_user = 'rabbitmq'
+ $rabbitmq_group = 'rabbitmq'
+ $rabbitmq_home = '/var/lib/rabbitmq'
+ $plugin_dir = "/usr/lib/rabbitmq/lib/rabbitmq_server-${version}/plugins"
+ }
+ 'Debian': {
+ $package_ensure = 'installed'
+ $package_name = 'rabbitmq-server'
+ $service_name = 'rabbitmq-server'
+ $package_provider = 'apt'
+ $version = '3.1.5'
+ $rabbitmq_user = 'rabbitmq'
+ $rabbitmq_group = 'rabbitmq'
+ $rabbitmq_home = '/var/lib/rabbitmq'
+ $plugin_dir = "/usr/lib/rabbitmq/lib/rabbitmq_server-${version}/plugins"
+ }
+ 'OpenBSD': {
+ $package_ensure = 'installed'
+ $package_name = 'rabbitmq'
+ $service_name = 'rabbitmq'
+ $version = '3.4.2'
+ $rabbitmq_user = '_rabbitmq'
+ $rabbitmq_group = '_rabbitmq'
+ $rabbitmq_home = '/var/rabbitmq'
+ $plugin_dir = '/usr/local/lib/rabbitmq/plugins'
+ }
+ 'RedHat': {
+ $package_ensure = 'installed'
+ $package_name = 'rabbitmq-server'
+ $service_name = 'rabbitmq-server'
+ $package_provider = 'rpm'
+ $version = '3.1.5-1'
+ $rabbitmq_user = 'rabbitmq'
+ $rabbitmq_group = 'rabbitmq'
+ $rabbitmq_home = '/var/lib/rabbitmq'
+ $plugin_dir = "/usr/lib/rabbitmq/lib/rabbitmq_server-${version}/plugins"
+ }
+ 'SUSE': {
+ $package_ensure = 'installed'
+ $package_name = 'rabbitmq-server'
+ $service_name = 'rabbitmq-server'
+ $package_provider = 'zypper'
+ $version = '3.1.5-1'
+ $rabbitmq_user = 'rabbitmq'
+ $rabbitmq_group = 'rabbitmq'
+ $rabbitmq_home = '/var/lib/rabbitmq'
+ $plugin_dir = "/usr/lib/rabbitmq/lib/rabbitmq_server-${version}/plugins"
+ }
+ default: {
+ fail("The ${module_name} module is not supported on an ${::osfamily} based system.")
+ }
+ }
+
+ #install
+ $admin_enable = true
+ $management_port = '15672'
+ $package_apt_pin = ''
+ $package_gpg_key = 'http://www.rabbitmq.com/rabbitmq-signing-key-public.asc'
+ $repos_ensure = true
+ $manage_repos = undef
+ $service_ensure = 'running'
+ $service_manage = true
+ #config
+ $cluster_node_type = 'disc'
+ $cluster_nodes = []
+ $config = 'rabbitmq/rabbitmq.config.erb'
+ $config_cluster = false
+ $config_path = '/etc/rabbitmq/rabbitmq.config'
+ $config_stomp = false
+ $default_user = 'guest'
+ $default_pass = 'guest'
+ $delete_guest_user = false
+ $env_config = 'rabbitmq/rabbitmq-env.conf.erb'
+ $env_config_path = '/etc/rabbitmq/rabbitmq-env.conf'
+ $erlang_cookie = undef
+ $interface = 'UNSET'
+ $node_ip_address = 'UNSET'
+ $port = '5672'
+ $tcp_keepalive = false
+ $ssl = false
+ $ssl_only = false
+ $ssl_cacert = 'UNSET'
+ $ssl_cert = 'UNSET'
+ $ssl_key = 'UNSET'
+ $ssl_port = '5671'
+ $ssl_interface = 'UNSET'
+ $ssl_management_port = '15671'
+ $ssl_stomp_port = '6164'
+ $ssl_verify = 'verify_none'
+ $ssl_fail_if_no_peer_cert = false
+ $ssl_versions = undef
+ $ssl_ciphers = []
+ $stomp_ensure = false
+ $ldap_auth = false
+ $ldap_server = 'ldap'
+ $ldap_user_dn_pattern = 'cn=username,ou=People,dc=example,dc=com'
+ $ldap_other_bind = 'anon'
+ $ldap_use_ssl = false
+ $ldap_port = '389'
+ $ldap_log = false
+ $ldap_config_variables = {}
+ $stomp_port = '6163'
+ $wipe_db_on_cookie_change = false
+ $cluster_partition_handling = 'ignore'
+ $environment_variables = {}
+ $config_variables = {}
+ $config_kernel_variables = {}
+ $file_limit = 16384
+}
--- /dev/null
+# requires
+# puppetlabs-apt
+# puppetlabs-stdlib
+class rabbitmq::repo::apt(
+ $location = 'http://www.rabbitmq.com/debian/',
+ $release = 'testing',
+ $repos = 'main',
+ $include_src = false,
+ $key = 'F78372A06FF50C80464FC1B4F7B8CEA6056E8E56',
+ $key_source = 'http://www.rabbitmq.com/rabbitmq-signing-key-public.asc',
+ $key_content = undef,
+ ) {
+
+ $pin = $rabbitmq::package_apt_pin
+
+ 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,
+ include_src => $include_src,
+ key => $key,
+ key_source => $key_source,
+ key_content => $key_content,
+ }
+
+ if $pin != '' {
+ validate_re($pin, '\d\d\d')
+ apt::pin { 'rabbitmq':
+ packages => 'rabbitmq-server',
+ priority => $pin,
+ }
+ }
+}
--- /dev/null
+# Class: rabbitmq::repo::rhel
+# Imports the gpg key if it doesn't already exist.
+class rabbitmq::repo::rhel {
+
+ if $rabbitmq::repos_ensure {
+
+ $package_gpg_key = $rabbitmq::package_gpg_key
+
+ 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',
+ }
+ }
+}
--- /dev/null
+# Class: rabbitmq::server
+#
+# This module manages the installation and config of the rabbitmq server
+# it has only been tested on certain version of debian-ish systems
+# Parameters:
+# [*port*] - port where rabbitmq server is hosted
+# [*delete_guest_user*] - rather or not to delete the default user
+# [*version*] - version of rabbitmq-server to install
+# [*package_name*] - name of rabbitmq package
+# [*service_name*] - name of rabbitmq service
+# [*service_ensure*] - desired ensure state for service
+# [*stomp_port*] - port stomp should be listening on
+# [*node_ip_address*] - ip address for rabbitmq to bind to
+# [*config*] - contents of config file
+# [*env_config*] - contents of env-config file
+# [*config_cluster*] - whether to configure a RabbitMQ cluster
+# [*cluster_nodes*] - which nodes to cluster with (including the current one)
+# [*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,
+# if the cookie indeed differs, then wiping the database is the *only* thing you
+# can do. You're only required to set this parameter to true as a sign that you
+# realise this.
+# Requires:
+# stdlib
+# Sample Usage:
+#
+# This module is used as backward compability layer for modules
+# which require rabbitmq::server instead of rabbitmq class.
+# It's still common uasge in many modules.
+#
+#
+# [Remember: No empty lines between comments and class definition]
+class rabbitmq::server(
+ $port = $rabbitmq::params::port,
+ $delete_guest_user = $rabbitmq::params::delete_guest_user,
+ $package_name = $rabbitmq::params::package_name,
+ $version = $rabbitmq::params::version,
+ $service_name = $rabbitmq::params::service_name,
+ $service_ensure = $rabbitmq::params::service_ensure,
+ $service_manage = $rabbitmq::params::service_manage,
+ $config_stomp = $rabbitmq::params::config_stomp,
+ $stomp_port = $rabbitmq::params::stomp_port,
+ $config_cluster = $rabbitmq::params::config_cluster,
+ $cluster_nodes = $rabbitmq::params::cluster_nodes,
+ $cluster_node_type = $rabbitmq::params::cluster_node_type,
+ $node_ip_address = $rabbitmq::params::node_ip_address,
+ $config = $rabbitmq::params::config,
+ $env_config = $rabbitmq::params::env_config,
+ $erlang_cookie = $rabbitmq::params::erlang_cookie,
+ $wipe_db_on_cookie_change = $rabbitmq::params::wipe_db_on_cookie_change,
+) inherits rabbitmq::params {
+
+ anchor {'before::rabbimq::class':
+ before => Class['rabbitmq'],
+ }
+
+ anchor {'after::rabbimq::class':
+ require => Class['rabbitmq'],
+ }
+
+ 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_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,
+ }
+}
--- /dev/null
+# Class: rabbitmq::service
+#
+# This class manages the rabbitmq server service itself.
+#
+# Parameters:
+#
+# Actions:
+#
+# Requires:
+#
+# Sample Usage:
+#
+class rabbitmq::service(
+ $service_ensure = $rabbitmq::service_ensure,
+ $service_manage = $rabbitmq::service_manage,
+ $service_name = $rabbitmq::service_name,
+) inherits rabbitmq {
+
+ validate_re($service_ensure, '^(running|stopped)$')
+ validate_bool($service_manage)
+
+ if ($service_manage) {
+ if $service_ensure == 'running' {
+ $ensure_real = 'running'
+ $enable_real = true
+ } else {
+ $ensure_real = 'stopped'
+ $enable_real = false
+ }
+
+ service { 'rabbitmq-server':
+ ensure => $ensure_real,
+ enable => $enable_real,
+ hasstatus => true,
+ hasrestart => true,
+ name => $service_name,
+ }
+ }
+
+}
--- /dev/null
+{
+ "name": "puppetlabs-rabbitmq",
+ "version": "5.2.1",
+ "author": "puppetlabs",
+ "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",
+ "operatingsystem_support": [
+ {
+ "operatingsystem": "RedHat",
+ "operatingsystemrelease": [
+ "5",
+ "6"
+ ]
+ },
+ {
+ "operatingsystem": "CentOS",
+ "operatingsystemrelease": [
+ "5",
+ "6"
+ ]
+ },
+ {
+ "operatingsystem": "Debian",
+ "operatingsystemrelease": [
+ "6",
+ "7"
+ ]
+ },
+ {
+ "operatingsystem": "Ubuntu",
+ "operatingsystemrelease": [
+ "12.04",
+ "14.04"
+ ]
+ }
+ ],
+ "requirements": [
+ {
+ "name": "pe",
+ "version_requirement": "3.x"
+ },
+ {
+ "name": "puppet",
+ "version_requirement": "3.x"
+ }
+ ],
+ "dependencies": [
+ {"name":"puppetlabs/stdlib","version_requirement":">=3.0.0 <5.0.0"},
+ {"name":"puppetlabs/apt","version_requirement":">=1.8.0 <2.0.0"},
+ {"name":"nanliu/staging","version_requirement":">=0.3.1 <2.0.0"}
+ ]
+}
--- /dev/null
+Specs
+=====
+
+The Puppet project uses RSpec for testing.
+
+For more information on RSpec, see http://rspec.info/
+
--- /dev/null
+require 'spec_helper_acceptance'
+
+describe 'rabbitmq class:' do
+ case fact('osfamily')
+ when 'RedHat'
+ package_name = 'rabbitmq-server'
+ service_name = 'rabbitmq-server'
+ when 'SUSE'
+ package_name = 'rabbitmq-server'
+ service_name = 'rabbitmq-server'
+ when 'Debian'
+ package_name = 'rabbitmq-server'
+ service_name = 'rabbitmq-server'
+ when 'Archlinux'
+ package_name = 'rabbitmq'
+ service_name = 'rabbitmq'
+ end
+
+ context "default class inclusion" do
+ it 'should run successfully' do
+ pp = <<-EOS
+ class { 'rabbitmq': }
+ if $::osfamily == 'RedHat' {
+ class { 'erlang': epel_enable => true}
+ Class['erlang'] -> Class['rabbitmq']
+ }
+ EOS
+
+ # Apply twice to ensure no errors the second time.
+ apply_manifest(pp, :catch_failures => true)
+ expect(apply_manifest(pp, :catch_changes => true).exit_code).to be_zero
+ end
+
+ describe package(package_name) do
+ it { should be_installed }
+ end
+
+ describe service(service_name) do
+ it { should be_enabled }
+ it { should be_running }
+ end
+ end
+
+ context "disable and stop service" do
+ it 'should run successfully' do
+ pp = <<-EOS
+ class { 'rabbitmq':
+ service_ensure => 'stopped',
+ }
+ if $::osfamily == 'RedHat' {
+ class { 'erlang': epel_enable => true}
+ Class['erlang'] -> Class['rabbitmq']
+ }
+ EOS
+
+ apply_manifest(pp, :catch_failures => true)
+ end
+
+ describe service(service_name) do
+ it { should_not be_enabled }
+ it { should_not be_running }
+ end
+ end
+
+ context "service is unmanaged" do
+ it 'should run successfully' do
+ pp_pre = <<-EOS
+ class { 'rabbitmq': }
+ if $::osfamily == 'RedHat' {
+ class { 'erlang': epel_enable => true}
+ Class['erlang'] -> Class['rabbitmq']
+ }
+ EOS
+
+ pp = <<-EOS
+ class { 'rabbitmq':
+ service_manage => false,
+ service_ensure => 'stopped',
+ }
+ if $::osfamily == 'RedHat' {
+ class { 'erlang': epel_enable => true}
+ Class['erlang'] -> Class['rabbitmq']
+ }
+ EOS
+
+ apply_manifest(pp_pre, :catch_failures => true)
+ apply_manifest(pp, :catch_failures => true)
+ end
+
+ describe service(service_name) do
+ it { should be_enabled }
+ it { should be_running }
+ end
+ end
+end
--- /dev/null
+require 'spec_helper_acceptance'
+
+describe 'rabbitmq clustering' 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' {
+ class { 'erlang': epel_enable => true}
+ Class['erlang'] -> Class['rabbitmq']
+ }
+ EOS
+
+ apply_manifest(pp, :catch_failures => true)
+ end
+
+ describe file('/etc/rabbitmq/rabbitmq.config') do
+ it { should be_file }
+ it { should contain 'cluster_nodes' }
+ it { should contain 'rabbit@rabbit1' }
+ it { should contain 'rabbit@rabbit2' }
+ it { should contain 'ram' }
+ end
+
+ describe file('/var/lib/rabbitmq/.erlang.cookie') do
+ it { should be_file }
+ it { should contain 'TESTCOOKIE' }
+ end
+ end
+end
--- /dev/null
+require 'spec_helper_acceptance'
+
+describe 'rabbitmq with delete_guest_user' do
+ context 'delete_guest_user' do
+ it 'should run successfully' do
+ pp = <<-EOS
+ class { 'rabbitmq':
+ port => '5672',
+ delete_guest_user => true,
+ }
+ if $::osfamily == 'RedHat' {
+ class { 'erlang': epel_enable => true}
+ Class['erlang'] -> Class['rabbitmq']
+ }
+ EOS
+
+ apply_manifest(pp, :catch_failures => true)
+ shell('rabbitmqctl list_users > /tmp/rabbitmqctl_users')
+ end
+
+ describe file('/tmp/rabbitmqctl_users') do
+ it { should be_file }
+ it { should_not contain 'guest' }
+ end
+ end
+end
--- /dev/null
+HOSTS:
+ centos-59-x64:
+ roles:
+ - master
+ platform: el-5-x86_64
+ box : centos-59-x64-vbox4210-nocm
+ box_url : http://puppet-vagrant-boxes.puppetlabs.com/centos-59-x64-vbox4210-nocm.box
+ hypervisor : vagrant
+CONFIG:
+ type: git
--- /dev/null
+HOSTS:
+ 'centos-6-vcloud':
+ roles:
+ - master
+ platform: el-6-x86_64
+ hypervisor: vcloud
+ template: centos-6-x86_64
+CONFIG:
+ type: foss
+ ssh:
+ keys: "~/.ssh/id_rsa-acceptance"
+ datastore: instance0
+ folder: Delivery/Quality Assurance/Enterprise/Dynamic
+ resourcepool: delivery/Quality Assurance/Enterprise/Dynamic
+ pooling_api: http://vcloud.delivery.puppetlabs.net/
+
--- /dev/null
+HOSTS:
+ centos-64-x64:
+ roles:
+ - master
+ - database
+ - dashboard
+ platform: el-6-x86_64
+ box : centos-64-x64-vbox4210-nocm
+ box_url : http://puppet-vagrant-boxes.puppetlabs.com/centos-64-x64-vbox4210-nocm.box
+ hypervisor : vagrant
+CONFIG:
+ type: pe
--- /dev/null
+HOSTS:
+ centos-65-x64:
+ roles:
+ - master
+ platform: el-6-x86_64
+ box : centos-65-x64-vbox436-nocm
+ box_url : http://puppet-vagrant-boxes.puppetlabs.com/centos-65-x64-virtualbox-nocm.box
+ hypervisor : vagrant
+CONFIG:
+ type: foss
--- /dev/null
+HOSTS:
+ 'debian-7-vcloud':
+ roles:
+ - master
+ platform: debian-7-x86_64
+ hypervisor: vcloud
+ template: debian-7-x86_64
+CONFIG:
+ type: foss
+ ssh:
+ keys: "~/.ssh/id_rsa-acceptance"
+ datastore: instance0
+ folder: Delivery/Quality Assurance/Enterprise/Dynamic
+ resourcepool: delivery/Quality Assurance/Enterprise/Dynamic
+ pooling_api: http://vcloud.delivery.puppetlabs.net/
+
--- /dev/null
+HOSTS:
+ centos-64-x64:
+ roles:
+ - master
+ platform: el-6-x86_64
+ box : centos-64-x64-vbox4210-nocm
+ box_url : http://puppet-vagrant-boxes.puppetlabs.com/centos-64-x64-vbox4210-nocm.box
+ hypervisor : vagrant
+CONFIG:
+ log_level: debug
+ type: git
--- /dev/null
+HOSTS:
+ ubuntu-server-10044-x64:
+ roles:
+ - master
+ platform: ubuntu-10.04-amd64
+ box : ubuntu-server-10044-x64-vbox4210-nocm
+ box_url : http://puppet-vagrant-boxes.puppetlabs.com/ubuntu-server-10044-x64-vbox4210-nocm.box
+ hypervisor : vagrant
+CONFIG:
+ type: foss
--- /dev/null
+HOSTS:
+ ubuntu-server-12042-x64:
+ roles:
+ - master
+ platform: ubuntu-12.04-amd64
+ box : ubuntu-server-12042-x64-vbox4210-nocm
+ box_url : http://puppet-vagrant-boxes.puppetlabs.com/ubuntu-server-12042-x64-vbox4210-nocm.box
+ hypervisor : vagrant
+CONFIG:
+ type: foss
--- /dev/null
+HOSTS:
+ ubuntu-server-1404-x64:
+ roles:
+ - master
+ platform: ubuntu-14.04-amd64
+ box : puppetlabs/ubuntu-14.04-64-nocm
+ box_url : https://vagrantcloud.com/puppetlabs/ubuntu-14.04-64-nocm
+ hypervisor : vagrant
+CONFIG:
+ log_level : debug
+ type: git
--- /dev/null
+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
--- /dev/null
+require 'spec_helper_acceptance'
+
+describe 'rabbitmq binding:' do
+
+
+ context "create binding and queue resources when rabbit using default management port" 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',
+ tags => ['monitoring', 'tag1'],
+ } ->
+
+ rabbitmq_user_permissions { 'dan@host1':
+ configure_permission => '.*',
+ read_permission => '.*',
+ write_permission => '.*',
+ }
+
+ rabbitmq_vhost { 'host1':
+ ensure => present,
+ } ->
+
+ rabbitmq_exchange { 'exchange1@host1':
+ user => 'dan',
+ password => 'bar',
+ type => 'topic',
+ ensure => present,
+ } ->
+
+ rabbitmq_queue { 'queue1@host1':
+ user => 'dan',
+ password => 'bar',
+ durable => true,
+ auto_delete => false,
+ ensure => present,
+ } ->
+
+ rabbitmq_binding { 'exchange1@queue1@host1':
+ user => 'dan',
+ password => 'bar',
+ destination_type => 'queue',
+ routing_key => '#',
+ ensure => present,
+ }
+
+ EOS
+
+ apply_manifest(pp, :catch_failures => true)
+ apply_manifest(pp, :catch_changes => true)
+ end
+
+ it 'should have the binding' do
+ shell('rabbitmqctl list_bindings -q -p host1') do |r|
+ expect(r.stdout).to match(/exchange1\sexchange\squeue1\squeue\s#/)
+ expect(r.exit_code).to be_zero
+ end
+ end
+
+ it 'should have the queue' do
+ shell('rabbitmqctl list_queues -q -p host1') do |r|
+ expect(r.stdout).to match(/queue1/)
+ expect(r.exit_code).to be_zero
+ end
+ end
+
+ end
+
+ context "create binding and queue resources when rabbit using a non-default management port" 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',
+ management_port => '11111',
+ delete_guest_user => true,
+ admin_enable => true,
+ } ->
+
+ rabbitmq_user { 'dan':
+ admin => true,
+ password => 'bar',
+ tags => ['monitoring', 'tag1'],
+ } ->
+
+ rabbitmq_user_permissions { 'dan@host2':
+ configure_permission => '.*',
+ read_permission => '.*',
+ write_permission => '.*',
+ }
+
+ rabbitmq_vhost { 'host2':
+ ensure => present,
+ } ->
+
+ rabbitmq_exchange { 'exchange2@host2':
+ user => 'dan',
+ password => 'bar',
+ type => 'topic',
+ ensure => present,
+ } ->
+
+ rabbitmq_queue { 'queue2@host2':
+ user => 'dan',
+ password => 'bar',
+ durable => true,
+ auto_delete => false,
+ ensure => present,
+ } ->
+
+ rabbitmq_binding { 'exchange2@queue2@host2':
+ user => 'dan',
+ password => 'bar',
+ destination_type => 'queue',
+ routing_key => '#',
+ ensure => present,
+ }
+
+ EOS
+
+ apply_manifest(pp, :catch_failures => true)
+ apply_manifest(pp, :catch_changes => true)
+ end
+
+ it 'should have the binding' do
+ shell('rabbitmqctl list_bindings -q -p host2') do |r|
+ expect(r.stdout).to match(/exchange2\sexchange\squeue2\squeue\s#/)
+ expect(r.exit_code).to be_zero
+ end
+ end
+
+ it 'should have the queue' do
+ shell('rabbitmqctl list_queues -q -p host2') do |r|
+ expect(r.stdout).to match(/queue2/)
+ expect(r.exit_code).to be_zero
+ end
+ end
+
+ end
+
+end
--- /dev/null
+require 'spec_helper_acceptance'
+
+describe 'rabbitmq::install::rabbitmqadmin class' do
+ context 'does nothing if service is unmanaged' do
+ it 'should run successfully' do
+ pp = <<-EOS
+ class { 'rabbitmq':
+ admin_enable => true,
+ service_manage => false,
+ }
+ if $::osfamily == 'RedHat' {
+ class { 'erlang': epel_enable => true}
+ Class['erlang'] -> Class['rabbitmq']
+ }
+ EOS
+
+ shell('rm -f /var/lib/rabbitmq/rabbitmqadmin')
+ apply_manifest(pp, :catch_failures => true)
+ end
+
+ describe file('/var/lib/rabbitmq/rabbitmqadmin') do
+ it { should_not be_file }
+ end
+ end
+
+ context 'downloads the cli tools' do
+ it 'should run successfully' do
+ pp = <<-EOS
+ class { 'rabbitmq':
+ admin_enable => true,
+ service_manage => true,
+ }
+ if $::osfamily == 'RedHat' {
+ class { 'erlang': epel_enable => true}
+ Class['erlang'] -> Class['rabbitmq']
+ }
+ EOS
+
+ apply_manifest(pp, :catch_failures => true)
+ end
+
+ describe file('/var/lib/rabbitmq/rabbitmqadmin') do
+ it { should be_file }
+ end
+ end
+
+ context 'works with specified default credentials' do
+ it 'should run successfully' do
+ # make sure credential change takes effect before admin_enable
+ pp_pre = <<-EOS
+ class { 'rabbitmq':
+ service_manage => true,
+ default_user => 'foobar',
+ default_pass => 'bazblam',
+ }
+ if $::osfamily == 'RedHat' {
+ class { 'erlang': epel_enable => true}
+ Class['erlang'] -> Class['rabbitmq']
+ }
+ EOS
+
+ pp = <<-EOS
+ class { 'rabbitmq':
+ admin_enable => true,
+ service_manage => true,
+ default_user => 'foobar',
+ default_pass => 'bazblam',
+ }
+ if $::osfamily == 'RedHat' {
+ class { 'erlang': epel_enable => true}
+ Class['erlang'] -> Class['rabbitmq']
+ }
+ EOS
+
+ shell('rm -f /var/lib/rabbitmq/rabbitmqadmin')
+ apply_manifest(pp_pre, :catch_failures => true)
+ apply_manifest(pp, :catch_failures => true)
+ end
+
+ describe file('/var/lib/rabbitmq/rabbitmqadmin') do
+ it { should be_file }
+ end
+ end
+
+end
--- /dev/null
+require 'spec_helper_acceptance'
+
+describe 'rabbitmq server:' do
+ case fact('osfamily')
+ when 'RedHat'
+ package_name = 'rabbitmq-server'
+ service_name = 'rabbitmq-server'
+ when 'SUSE'
+ package_name = 'rabbitmq-server'
+ service_name = 'rabbitmq-server'
+ when 'Debian'
+ package_name = 'rabbitmq-server'
+ service_name = 'rabbitmq-server'
+ when 'Archlinux'
+ package_name = 'rabbitmq'
+ service_name = 'rabbitmq'
+ end
+
+ context "default class inclusion" do
+ it 'should run successfully' do
+ pp = <<-EOS
+ class { 'rabbitmq::server': }
+ if $::osfamily == 'RedHat' {
+ class { 'erlang': epel_enable => true}
+ Class['erlang'] -> Class['rabbitmq::server']
+ }
+ EOS
+
+ # Apply twice to ensure no errors the second time.
+ apply_manifest(pp, :catch_failures => true)
+ expect(apply_manifest(pp, :catch_changes => true).exit_code).to be_zero
+ end
+
+ describe package(package_name) do
+ it { should be_installed }
+ end
+
+ describe service(service_name) do
+ it { should be_enabled }
+ it { should be_running }
+ end
+ end
+
+ context "disable and stop service" do
+ it 'should run successfully' do
+ pp = <<-EOS
+ class { 'rabbitmq::server':
+ service_ensure => 'stopped',
+ }
+ if $::osfamily == 'RedHat' {
+ class { 'erlang': epel_enable => true}
+ Class['erlang'] -> Class['rabbitmq::server']
+ }
+ EOS
+
+ apply_manifest(pp, :catch_failures => true)
+ end
+
+ describe service(service_name) do
+ it { should_not be_enabled }
+ it { should_not be_running }
+ end
+ end
+
+ context "service is unmanaged" do
+ it 'should run successfully' do
+ pp_pre = <<-EOS
+ class { 'rabbitmq::server': }
+ if $::osfamily == 'RedHat' {
+ class { 'erlang': epel_enable => true}
+ Class['erlang'] -> Class['rabbitmq::server']
+ }
+ EOS
+
+ pp = <<-EOS
+ class { 'rabbitmq::server':
+ service_manage => false,
+ service_ensure => 'stopped',
+ }
+ if $::osfamily == 'RedHat' {
+ class { 'erlang': epel_enable => true}
+ Class['erlang'] -> Class['rabbitmq::server']
+ }
+ EOS
+
+
+ apply_manifest(pp_pre, :catch_failures => true)
+ apply_manifest(pp, :catch_failures => true)
+ end
+
+ describe service(service_name) do
+ it { should be_enabled }
+ it { should be_running }
+ end
+ end
+end
--- /dev/null
+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
--- /dev/null
+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
--- /dev/null
+require 'spec_helper_acceptance'
+#
+# beacuse of some serious issues with upgrading and downgrading rabbitmq on RedHat,
+# we need to run all of the 2.8.1 tests last.
+#
+# NOTE that this is only tested on RedHat and probably only works there. But I can't seem
+# to get 'confine' to work...
+#
+
+describe 'rabbitmq class with 2.8.1:' do
+ case fact('osfamily')
+ when 'RedHat'
+ package_name = 'rabbitmq-server'
+ service_name = 'rabbitmq-server'
+ package_source = "http://www.rabbitmq.com/releases/rabbitmq-server/v2.8.1/rabbitmq-server-2.8.1-1.noarch.rpm"
+ package_ensure = '2.8.1-1'
+ when 'SUSE'
+ package_name = 'rabbitmq-server'
+ service_name = 'rabbitmq-server'
+ package_source = "http://www.rabbitmq.com/releases/rabbitmq-server/v2.8.1/rabbitmq-server-2.8.1-1.noarch.rpm"
+ package_ensure = '2.8.1-1'
+ when 'Debian'
+ package_name = 'rabbitmq-server'
+ service_name = 'rabbitmq-server'
+ package_source = ''
+ package_ensure = '2.8.1'
+ when 'Archlinux'
+ package_name = 'rabbitmq'
+ service_name = 'rabbitmq'
+ package_source = ''
+ package_ensure = '2.8.1'
+ end
+
+ context "default class inclusion" do
+ it 'should run successfully' do
+ pp = <<-EOS
+ class { 'rabbitmq':
+ version => '2.8.1-1',
+ package_source => '#{package_source}',
+ package_ensure => '#{package_ensure}',
+ package_provider => 'rpm',
+ management_port => '55672',
+ }
+ if $::osfamily == 'RedHat' {
+ class { 'erlang': epel_enable => true}
+ Class['erlang'] -> Class['rabbitmq']
+ }
+ EOS
+
+ # clean up previous 3.x install - can't be ungraded cleanly via RPM
+ shell('service rabbitmq-server stop')
+ shell('yum -y erase rabbitmq-server')
+ shell('rm -Rf /var/lib/rabbitmq/mnesia /etc/rabbitmq /var/lib/rabbitmq/rabbitmqadmin')
+ # Apply twice to ensure no errors the second time.
+ apply_manifest(pp, :catch_failures => true)
+ expect(apply_manifest(pp, :catch_changes => true).exit_code).to be_zero
+ # DEBUG
+ shell('netstat -lntp')
+ end
+
+ describe command('rabbitmqctl status') do
+ its(:stdout) { should match /{rabbit,"RabbitMQ","2.8.1"}/ }
+ end
+
+ describe package(package_name) do
+ it { should be_installed }
+ end
+
+ describe service(service_name) do
+ it { should be_enabled }
+ it { should be_running }
+ end
+ end
+
+ context "disable and stop service" do
+ it 'should run successfully' do
+ pp = <<-EOS
+ class { 'rabbitmq':
+ version => '2.8.1-1',
+ package_source => '#{package_source}',
+ package_ensure => '#{package_ensure}',
+ package_provider => 'rpm',
+ management_port => '55672',
+ service_ensure => 'stopped',
+ admin_enable => false,
+ }
+ if $::osfamily == 'RedHat' {
+ class { 'erlang': epel_enable => true}
+ Class['erlang'] -> Class['rabbitmq']
+ }
+ EOS
+
+ apply_manifest(pp, :catch_failures => true)
+ end
+
+ describe service(service_name) do
+ it { should_not be_enabled }
+ it { should_not be_running }
+ end
+ end
+
+ context "service is unmanaged" do
+ it 'should run successfully' do
+ pp_pre = <<-EOS
+ class { 'rabbitmq':
+ version => '2.8.1-1',
+ package_source => '#{package_source}',
+ package_ensure => '#{package_ensure}',
+ package_provider => 'rpm',
+ management_port => '55672',
+ }
+ if $::osfamily == 'RedHat' {
+ class { 'erlang': epel_enable => true}
+ Class['erlang'] -> Class['rabbitmq']
+ }
+ EOS
+
+ pp = <<-EOS
+ class { 'rabbitmq':
+ service_manage => false,
+ service_ensure => 'stopped',
+ }
+ if $::osfamily == 'RedHat' {
+ class { 'erlang': epel_enable => true}
+ Class['erlang'] -> Class['rabbitmq']
+ }
+ EOS
+
+ apply_manifest(pp_pre, :catch_failures => true)
+ apply_manifest(pp, :catch_failures => true)
+ end
+
+ describe service(service_name) do
+ it { should be_enabled }
+ it { should be_running }
+ end
+ end
+
+ context 'rabbitmqadmin' do
+ #confine :to, :platform => 'el-6-x86'
+
+ it 'should run successfully' do
+ pp = <<-EOS
+ class { 'rabbitmq':
+ admin_enable => true,
+ service_manage => true,
+ version => '2.8.1-1',
+ package_source => '#{package_source}',
+ package_ensure => '#{package_ensure}',
+ package_provider => 'rpm',
+ management_port => '55672',
+ }
+ if $::osfamily == 'RedHat' {
+ class { 'erlang': epel_enable => true}
+ Class['erlang'] -> Class['rabbitmq']
+ }
+ EOS
+
+ shell('rm -f /var/lib/rabbitmq/rabbitmqadmin')
+ apply_manifest(pp, :catch_failures => true)
+ end
+
+ # since serverspec (used by beaker-rspec) can only tell present/absent for packages
+ describe file('/var/lib/rabbitmq/rabbitmqadmin') do
+ it { should be_file }
+ end
+
+ describe command('/usr/local/bin/rabbitmqadmin --help') do
+ its(:exit_status) { should eq 0 }
+ end
+
+ end
+
+ context 'rabbitmqadmin with specified default credentials' do
+
+ it 'should run successfully' do
+ # make sure credential change takes effect before admin_enable
+ pp = <<-EOS
+ class { 'rabbitmq':
+ admin_enable => true,
+ service_manage => true,
+ version => '2.8.1-1',
+ package_source => '#{package_source}',
+ package_ensure => '#{package_ensure}',
+ package_provider => 'rpm',
+ management_port => '55672',
+ default_user => 'foobar',
+ default_pass => 'bazblam',
+ }
+ if $::osfamily == 'RedHat' {
+ class { 'erlang': epel_enable => true}
+ Class['erlang'] -> Class['rabbitmq']
+ }
+ EOS
+
+ # next 3 lines - see MODULES-1085
+ shell('service rabbitmq-server stop')
+ shell('rm -Rf /var/lib/rabbitmq/mnesia /var/lib/rabbitmq/rabbitmqadmin')
+ apply_manifest(pp, :catch_failures => true)
+ end
+
+ # since serverspec (used by beaker-rspec) can only tell present/absent for packages
+ describe file('/var/lib/rabbitmq/rabbitmqadmin') do
+ it { should be_file }
+ end
+
+ describe command('/usr/local/bin/rabbitmqadmin --help') do
+ its(:exit_status) { should eq 0 }
+ end
+
+ end
+
+end
--- /dev/null
+require 'spec_helper'
+
+describe 'rabbitmq' do
+
+ context 'on unsupported distributions' do
+ let(:facts) {{ :osfamily => 'Unsupported' }}
+
+ it 'we fail' do
+ expect { catalogue }.to raise_error(Puppet::Error, /not supported on an Unsupported/)
+ end
+ end
+
+ context 'on Debian' do
+ 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 }}
+ let(:facts) {{ :osfamily => 'Debian', :lsbdistid => 'Debian', :lsbdistcodename => 'squeeze' }}
+ 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(:facts) {{ :osfamily => 'Debian', :lsbdistid => 'Debian', :lsbdistcodename => 'squeeze' }}
+ context 'with manage_repos => false and repos_ensure => false' do
+ let(:params) {{ :manage_repos => false, :repos_ensure => false }}
+ 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
+
+ context 'with file_limit => unlimited' do
+ let(:params) {{ :file_limit => 'unlimited' }}
+ it { should contain_file('/etc/default/rabbitmq-server').with_content(/ulimit -n unlimited/) }
+ end
+
+ context 'with file_limit => infinity' do
+ let(:params) {{ :file_limit => 'infinity' }}
+ it { should contain_file('/etc/default/rabbitmq-server').with_content(/ulimit -n infinity/) }
+ end
+
+ context 'with file_limit => -1' do
+ let(:params) {{ :file_limit => -1 }}
+ it { should contain_file('/etc/default/rabbitmq-server').with_content(/ulimit -n -1/) }
+ end
+
+ context 'with file_limit => \'1234\'' do
+ let(:params) {{ :file_limit => '1234' }}
+ it { should contain_file('/etc/default/rabbitmq-server').with_content(/ulimit -n 1234/) }
+ end
+
+ context 'with file_limit => foo' do
+ let(:params) {{ :file_limit => 'foo' }}
+ it 'does not compile' do
+ expect { catalogue }.to raise_error(Puppet::Error, /\$file_limit must be an integer, 'unlimited', or 'infinity'/)
+ end
+ end
+ end
+
+ context 'on Redhat' do
+ 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 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
+
+ context 'on RedHat 7.0 or more' do
+ let(:facts) {{ :osfamily => 'RedHat', :operatingsystemmajrelease => '7' }}
+
+ it { should contain_file('/etc/systemd/system/rabbitmq-server.service.d').with(
+ 'ensure' => 'directory',
+ 'owner' => '0',
+ 'group' => '0',
+ 'mode' => '0755',
+ 'selinux_ignore_defaults' => true
+ ) }
+
+ it { should contain_exec('rabbitmq-systemd-reload').with(
+ 'command' => '/usr/bin/systemctl daemon-reload',
+ 'notify' => 'Class[Rabbitmq::Service]',
+ 'refreshonly' => true
+ ) }
+ context 'with file_limit => unlimited' do
+ let(:params) {{ :file_limit => 'unlimited' }}
+ it { should contain_file('/etc/systemd/system/rabbitmq-server.service.d/limits.conf').with(
+ 'owner' => '0',
+ 'group' => '0',
+ 'mode' => '0644',
+ 'notify' => 'Exec[rabbitmq-systemd-reload]',
+ 'content' => '[Service]
+LimitNOFILE=unlimited
+'
+ ) }
+ end
+
+ context 'with file_limit => infinity' do
+ let(:params) {{ :file_limit => 'infinity' }}
+ it { should contain_file('/etc/systemd/system/rabbitmq-server.service.d/limits.conf').with(
+ 'owner' => '0',
+ 'group' => '0',
+ 'mode' => '0644',
+ 'notify' => 'Exec[rabbitmq-systemd-reload]',
+ 'content' => '[Service]
+LimitNOFILE=infinity
+'
+ ) }
+ end
+
+ context 'with file_limit => -1' do
+ let(:params) {{ :file_limit => -1 }}
+ it { should contain_file('/etc/systemd/system/rabbitmq-server.service.d/limits.conf').with(
+ 'owner' => '0',
+ 'group' => '0',
+ 'mode' => '0644',
+ 'notify' => 'Exec[rabbitmq-systemd-reload]',
+ 'content' => '[Service]
+LimitNOFILE=-1
+'
+ ) }
+ end
+
+ context 'with file_limit => \'1234\'' do
+ let(:params) {{ :file_limit => '1234' }}
+ it { should contain_file('/etc/systemd/system/rabbitmq-server.service.d/limits.conf').with(
+ 'owner' => '0',
+ 'group' => '0',
+ 'mode' => '0644',
+ 'notify' => 'Exec[rabbitmq-systemd-reload]',
+ 'content' => '[Service]
+LimitNOFILE=1234
+'
+ ) }
+ end
+
+ context 'with file_limit => foo' do
+ let(:params) {{ :file_limit => 'foo' }}
+ it 'does not compile' do
+ expect { catalogue }.to raise_error(Puppet::Error, /\$file_limit must be an integer, 'unlimited', or 'infinity'/)
+ end
+ end
+ end
+
+ context 'on RedHat before 7.0' do
+ let(:facts) {{ :osfamily => 'RedHat', :operatingsystemmajrelease => '6' }}
+
+ context 'with file_limit => unlimited' do
+ let(:params) {{ :file_limit => 'unlimited' }}
+ it { should contain_file('/etc/security/limits.d/rabbitmq-server.conf').with(
+ 'owner' => '0',
+ 'group' => '0',
+ 'mode' => '0644',
+ 'notify' => 'Class[Rabbitmq::Service]',
+ 'content' => 'rabbitmq soft nofile unlimited
+rabbitmq hard nofile unlimited
+'
+ ) }
+ end
+
+ context 'with file_limit => infinity' do
+ let(:params) {{ :file_limit => 'infinity' }}
+ it { should contain_file('/etc/security/limits.d/rabbitmq-server.conf').with(
+ 'owner' => '0',
+ 'group' => '0',
+ 'mode' => '0644',
+ 'notify' => 'Class[Rabbitmq::Service]',
+ 'content' => 'rabbitmq soft nofile infinity
+rabbitmq hard nofile infinity
+'
+ ) }
+ end
+
+ context 'with file_limit => -1' do
+ let(:params) {{ :file_limit => -1 }}
+ it { should contain_file('/etc/security/limits.d/rabbitmq-server.conf').with(
+ 'owner' => '0',
+ 'group' => '0',
+ 'mode' => '0644',
+ 'notify' => 'Class[Rabbitmq::Service]',
+ 'content' => 'rabbitmq soft nofile -1
+rabbitmq hard nofile -1
+'
+ ) }
+ end
+
+ context 'with file_limit => \'1234\'' do
+ let(:params) {{ :file_limit => '1234' }}
+ it { should contain_file('/etc/security/limits.d/rabbitmq-server.conf').with(
+ 'owner' => '0',
+ 'group' => '0',
+ 'mode' => '0644',
+ 'notify' => 'Class[Rabbitmq::Service]',
+ 'content' => 'rabbitmq soft nofile 1234
+rabbitmq hard nofile 1234
+'
+ ) }
+ end
+
+ context 'with file_limit => foo' do
+ let(:params) {{ :file_limit => 'foo' }}
+ it 'does not compile' do
+ expect { catalogue }.to raise_error(Puppet::Error, /\$file_limit must be an integer, 'unlimited', or 'infinity'/)
+ end
+ end
+ end
+
+ ['Debian', 'RedHat', 'SUSE', 'Archlinux'].each do |distro|
+ context "on #{distro}" do
+ let(:facts) {{
+ :osfamily => distro,
+ :lsbdistcodename => 'squeeze',
+ :lsbdistid => 'Debian'
+ }}
+
+ it { should contain_class('rabbitmq::install') }
+ it { should contain_class('rabbitmq::config') }
+ it { should contain_class('rabbitmq::service') }
+
+ context 'with admin_enable set to true' do
+ let(:params) {{ :admin_enable => true }}
+ context 'with service_manage set to true' do
+ it 'we enable the admin interface by default' do
+ should contain_class('rabbitmq::install::rabbitmqadmin')
+ should contain_rabbitmq_plugin('rabbitmq_management').with(
+ 'require' => 'Class[Rabbitmq::Install]',
+ 'notify' => 'Class[Rabbitmq::Service]'
+ )
+ should contain_staging__file('rabbitmqadmin').with_source("http://guest:guest@localhost:15672/cli/rabbitmqadmin")
+ end
+ end
+ context 'with service_manage set to true and default user/pass specified' do
+ let(:params) {{ :admin_enable => true, :default_user => 'foobar', :default_pass => 'hunter2' }}
+ it 'we use the correct URL to rabbitmqadmin' do
+ should contain_staging__file('rabbitmqadmin').with_source("http://foobar:hunter2@localhost:15672/cli/rabbitmqadmin")
+ end
+ end
+ context 'with service_manage set to true and management port specified' do
+ # note that the 2.x management port is 55672 not 15672
+ let(:params) {{ :admin_enable => true, :management_port => '55672' }}
+ it 'we use the correct URL to rabbitmqadmin' do
+ should contain_staging__file('rabbitmqadmin').with_source("http://guest:guest@localhost:55672/cli/rabbitmqadmin")
+ end
+ end
+ context 'with service_manage set to false' do
+ let(:params) {{ :admin_enable => true, :service_manage => false }}
+ it 'should do nothing' do
+ should_not contain_class('rabbitmq::install::rabbitmqadmin')
+ should_not contain_rabbitmq_plugin('rabbitmq_management')
+ end
+ end
+ end
+
+ describe 'manages configuration directory correctly' do
+ it { should contain_file('/etc/rabbitmq').with(
+ 'ensure' => 'directory'
+ )}
+ end
+
+ describe 'manages configuration file correctly' do
+ it { should contain_file('rabbitmq.config') }
+ end
+
+ context 'configures config_cluster' do
+ let(:facts) {{ :osfamily => distro, :lsbdistid => 'Debian' }}
+ let(:params) {{
+ :config_cluster => true,
+ :cluster_nodes => ['hare-1', 'hare-2'],
+ :cluster_node_type => 'ram',
+ :wipe_db_on_cookie_change => false
+ }}
+
+ describe 'with defaults' do
+ it 'fails' do
+ expect { catalogue }.to raise_error(Puppet::Error, /You must set the \$erlang_cookie value/)
+ end
+ end
+
+ describe 'with erlang_cookie set' do
+ let(:params) {{
+ :config_cluster => true,
+ :cluster_nodes => ['hare-1', 'hare-2'],
+ :cluster_node_type => 'ram',
+ :erlang_cookie => 'TESTCOOKIE',
+ :wipe_db_on_cookie_change => true
+ }}
+ it 'contains the rabbitmq_erlang_cookie' do
+ should contain_rabbitmq_erlang_cookie('/var/lib/rabbitmq/.erlang.cookie')
+ end
+ end
+
+ describe 'and sets appropriate configuration' 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 'for cluster_nodes' do
+ should contain_file('rabbitmq.config').with({
+ 'content' => /cluster_nodes.*\['rabbit@hare-1', 'rabbit@hare-2'\], ram/,
+ })
+ end
+
+ end
+ end
+
+ describe 'rabbitmq-env configuration' do
+ let(:params) {{ :environment_variables => {
+ '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(/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
+
+ context 'delete_guest_user' do
+ describe 'should do nothing by default' do
+ it { should_not contain_rabbitmq_user('guest') }
+ end
+
+ describe 'delete user when delete_guest_user set' do
+ let(:params) {{ :delete_guest_user => true }}
+ it 'removes the user' do
+ should contain_rabbitmq_user('guest').with(
+ 'ensure' => 'absent',
+ 'provider' => 'rabbitmqctl'
+ )
+ end
+ end
+ end
+
+ context 'configuration setting' do
+ describe 'node_ip_address when set' do
+ let(:params) {{ :node_ip_address => '172.0.0.1' }}
+ it 'should set NODE_IP_ADDRESS to specified value' do
+ should contain_file('rabbitmq-env.config').
+ with_content(%r{NODE_IP_ADDRESS=172\.0\.0\.1})
+ end
+ end
+
+ describe 'stomp by default' do
+ it 'should not specify stomp parameters in rabbitmq.config' do
+ should contain_file('rabbitmq.config').without({
+ 'content' => /stomp/,})
+ end
+ end
+ describe 'stomp when set' do
+ let(:params) {{ :config_stomp => true, :stomp_port => 5679 }}
+ it 'should specify stomp port in rabbitmq.config' do
+ should contain_file('rabbitmq.config').with({
+ 'content' => /rabbitmq_stomp.*tcp_listeners, \[5679\]/m,
+ })
+ end
+ end
+ describe 'stomp when set ssl port w/o ssl enabled' do
+ let(:params) {{ :config_stomp => true, :stomp_port => 5679, :ssl => false, :ssl_stomp_port => 5680 }}
+ it 'should not configure ssl_listeners in rabbitmq.config' do
+ should contain_file('rabbitmq.config').without({
+ 'content' => /rabbitmq_stomp.*ssl_listeners, \[5680\]/m,
+ })
+ end
+ end
+ describe 'stomp when set with ssl' do
+ let(:params) {{ :config_stomp => true, :stomp_port => 5679, :ssl => true, :ssl_stomp_port => 5680 }}
+ it 'should specify stomp port and ssl stomp port in rabbitmq.config' do
+ should contain_file('rabbitmq.config').with({
+ 'content' => /rabbitmq_stomp.*tcp_listeners, \[5679\].*ssl_listeners, \[5680\]/m,
+ })
+ end
+ end
+ end
+
+ describe 'configuring ldap authentication' do
+ let :params do
+ { :config_stomp => true,
+ :ldap_auth => true,
+ :ldap_server => 'ldap.example.com',
+ :ldap_user_dn_pattern => 'ou=users,dc=example,dc=com',
+ :ldap_other_bind => 'as_user',
+ :ldap_use_ssl => false,
+ :ldap_port => '389',
+ :ldap_log => true,
+ :ldap_config_variables => { 'foo' => 'bar' }
+ }
+ end
+
+ it { should contain_rabbitmq_plugin('rabbitmq_auth_backend_ldap') }
+
+ it 'should contain ldap parameters' do
+ verify_contents(catalogue, 'rabbitmq.config',
+ ['[', ' {rabbit, [', ' {auth_backends, [rabbit_auth_backend_internal, rabbit_auth_backend_ldap]},', ' ]}',
+ ' {rabbitmq_auth_backend_ldap, [', ' {other_bind, as_user},',
+ ' {servers, ["ldap.example.com"]},',
+ ' {user_dn_pattern, "ou=users,dc=example,dc=com"},', ' {use_ssl, false},',
+ ' {port, 389},', ' {foo, bar},', ' {log, true}'])
+ end
+ end
+
+ describe 'configuring ldap authentication' do
+ let :params do
+ { :config_stomp => false,
+ :ldap_auth => true,
+ :ldap_server => 'ldap.example.com',
+ :ldap_user_dn_pattern => 'ou=users,dc=example,dc=com',
+ :ldap_other_bind => 'as_user',
+ :ldap_use_ssl => false,
+ :ldap_port => '389',
+ :ldap_log => true,
+ :ldap_config_variables => { 'foo' => 'bar' }
+ }
+ end
+
+ it { should contain_rabbitmq_plugin('rabbitmq_auth_backend_ldap') }
+
+ it 'should contain ldap parameters' do
+ verify_contents(catalogue, 'rabbitmq.config',
+ ['[', ' {rabbit, [', ' {auth_backends, [rabbit_auth_backend_internal, rabbit_auth_backend_ldap]},', ' ]}',
+ ' {rabbitmq_auth_backend_ldap, [', ' {other_bind, as_user},',
+ ' {servers, ["ldap.example.com"]},',
+ ' {user_dn_pattern, "ou=users,dc=example,dc=com"},', ' {use_ssl, false},',
+ ' {port, 389},', ' {foo, bar},', ' {log, true}'])
+ end
+ end
+
+ describe 'default_user and default_pass set' do
+ let(:params) {{ :default_user => 'foo', :default_pass => 'bar' }}
+ it 'should set default_user and default_pass to specified values' do
+ should contain_file('rabbitmq.config').with({
+ 'content' => /default_user, <<"foo">>.*default_pass, <<"bar">>/m,
+ })
+ end
+ end
+
+ describe 'interfaces option with no ssl' do
+ let(:params) {
+ { :interface => '0.0.0.0',
+ } }
+
+ it 'should set ssl options to specified values' do
+ should contain_file('rabbitmq.config').with_content(%r{tcp_listeners, \[\{"0.0.0.0", 5672\}\]})
+ end
+ end
+
+ describe 'ssl options' do
+ let(:params) {
+ { :ssl => true,
+ :ssl_port => 3141,
+ :ssl_cacert => '/path/to/cacert',
+ :ssl_cert => '/path/to/cert',
+ :ssl_key => '/path/to/key'
+ } }
+
+ 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, \[}
+ )
+ should contain_file('rabbitmq.config').with_content(
+ %r{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"}
+ )
+ end
+ end
+
+
+ describe 'ssl options with ssl_interfaces' do
+ let(:params) {
+ { :ssl => true,
+ :ssl_port => 3141,
+ :ssl_interface => '0.0.0.0',
+ :ssl_cacert => '/path/to/cacert',
+ :ssl_cert => '/path/to/cert',
+ :ssl_key => '/path/to/key'
+ } }
+
+ it 'should set ssl options to specified values' do
+ should contain_file('rabbitmq.config').with_content(%r{ssl_listeners, \[\{"0.0.0.0", 3141\}\]})
+ should contain_file('rabbitmq.config').with_content(%r{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})
+ end
+ end
+
+
+
+ describe 'ssl options with ssl_only' do
+ let(:params) {
+ { :ssl => true,
+ :ssl_only => true,
+ :ssl_port => 3141,
+ :ssl_cacert => '/path/to/cacert',
+ :ssl_cert => '/path/to/cert',
+ :ssl_key => '/path/to/key'
+ } }
+
+ it 'should set ssl options to specified values' do
+ should contain_file('rabbitmq.config').with_content(%r{tcp_listeners, \[\]})
+ should contain_file('rabbitmq.config').with_content(%r{ssl_listeners, \[3141\]})
+ should contain_file('rabbitmq.config').with_content(%r{ssl_options, \[})
+ should contain_file('rabbitmq.config').with_content(%r{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})
+ end
+ end
+
+ describe 'ssl options with ssl_only and ssl_interfaces' do
+ let(:params) {
+ { :ssl => true,
+ :ssl_only => true,
+ :ssl_port => 3141,
+ :ssl_interface => '0.0.0.0',
+ :ssl_cacert => '/path/to/cacert',
+ :ssl_cert => '/path/to/cert',
+ :ssl_key => '/path/to/key'
+ } }
+
+ it 'should set ssl options to specified values' do
+ should contain_file('rabbitmq.config').with_content(%r{tcp_listeners, \[\]})
+ should contain_file('rabbitmq.config').with_content(%r{ssl_listeners, \[\{"0.0.0.0", 3141\}\]})
+ should contain_file('rabbitmq.config').with_content(%r{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})
+ 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, \[})
+ should contain_file('rabbitmq.config').with_content(%r{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 { catalogue }.to raise_error(Puppet::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 { catalogue }.to raise_error(Puppet::Error, /\$ssl_versions requires that \$ssl => true/)
+ end
+ end
+
+ describe 'ssl options with ssl ciphers' do
+ let(:params) {
+ { :ssl => true,
+ :ssl_port => 3141,
+ :ssl_cacert => '/path/to/cacert',
+ :ssl_cert => '/path/to/cert',
+ :ssl_key => '/path/to/key',
+ :ssl_ciphers => ['ecdhe_rsa,aes_256_cbc,sha', 'dhe_rsa,aes_256_cbc,sha']
+ } }
+
+ it 'should set ssl ciphers to specified values' do
+ should contain_file('rabbitmq.config').with_content(%r{ciphers,\[[[:space:]]+{dhe_rsa,aes_256_cbc,sha},[[:space:]]+{ecdhe_rsa,aes_256_cbc,sha}[[:space:]]+\]})
+ 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,
+ :ssl_management_port => 3141,
+ :ssl_cacert => '/path/to/cacert',
+ :ssl_cert => '/path/to/cert',
+ :ssl_key => '/path/to/key',
+ :admin_enable => true
+ } }
+
+ it 'should set rabbitmq_management ssl options 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, 3141\}})
+ 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"\}[\r\n ]*\]\}})
+ end
+ end
+
+ describe 'admin without ssl' do
+ let(:params) {
+ { :ssl => false,
+ :management_port => 3141,
+ :admin_enable => true
+ } }
+
+ it 'should set rabbitmq_management options 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, 3141\}})
+ end
+ end
+
+ describe 'ssl admin options' do
+ let(:params) {
+ { :ssl => true,
+ :ssl_management_port => 3141,
+ :ssl_cacert => '/path/to/cacert',
+ :ssl_cert => '/path/to/cert',
+ :ssl_key => '/path/to/key',
+ :admin_enable => true
+ } }
+
+ it 'should set rabbitmq_management ssl options 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, 3141\},})
+ 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"\}[\r\n ]*\]\}})
+ end
+ end
+
+ describe 'admin without ssl' do
+ let(:params) {
+ { :ssl => false,
+ :management_port => 3141,
+ :admin_enable => true
+ } }
+
+ it 'should set rabbitmq_management options to specified values' do
+ should contain_file('rabbitmq.config') \
+ .with_content(/\{rabbitmq_management, \[/) \
+ .with_content(/\{listener, \[/) \
+ .with_content(/\{port, 3141\}/)
+ end
+ end
+
+ describe 'config_variables options' do
+ let(:params) {{ :config_variables => {
+ 'hipe_compile' => true,
+ 'vm_memory_high_watermark' => 0.4,
+ 'frame_max' => 131072,
+ 'collect_statistics' => "none",
+ 'auth_mechanisms' => "['PLAIN', 'AMQPLAIN']",
+ }}}
+ it 'should set environment variables' do
+ should contain_file('rabbitmq.config') \
+ .with_content(/\{hipe_compile, true\}/) \
+ .with_content(/\{vm_memory_high_watermark, 0.4\}/) \
+ .with_content(/\{frame_max, 131072\}/) \
+ .with_content(/\{collect_statistics, none\}/) \
+ .with_content(/\{auth_mechanisms, \['PLAIN', 'AMQPLAIN'\]\}/)
+ end
+ end
+
+ describe 'config_kernel_variables options' do
+ let(:params) {{ :config_kernel_variables => {
+ 'inet_dist_listen_min' => 9100,
+ 'inet_dist_listen_max' => 9105,
+ }}}
+ 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\}/)
+ end
+ end
+
+ describe 'tcp_keepalive enabled' do
+ let(:params) {{ :tcp_keepalive => true }}
+ it 'should set tcp_listen_options keepalive true' do
+ should contain_file('rabbitmq.config') \
+ .with_content(/\{tcp_listen_options, \[\{keepalive, true\}\]\},/)
+ end
+ end
+
+ describe 'tcp_keepalive disabled (default)' do
+ it 'should not set tcp_listen_options' do
+ should contain_file('rabbitmq.config') \
+ .without_content(/\{tcp_listen_options, \[\{keepalive, true\}\]\},/)
+ end
+ end
+
+ describe 'non-bool tcp_keepalive parameter' do
+ let :params do
+ { :tcp_keepalive => 'string' }
+ end
+
+ it 'should raise an error' do
+ expect {
+ should contain_file('rabbitmq.config')
+ }.to raise_error(Puppet::Error, /is not a boolean/)
+ end
+ end
+
+ context 'delete_guest_user' do
+ describe 'should do nothing by default' do
+ it { should_not contain_rabbitmq_user('guest') }
+ end
+
+ describe 'delete user when delete_guest_user set' do
+ let(:params) {{ :delete_guest_user => true }}
+ it 'removes the user' do
+ should contain_rabbitmq_user('guest').with(
+ 'ensure' => 'absent',
+ 'provider' => 'rabbitmqctl'
+ )
+ end
+ end
+ end
+
+ ##
+ ## rabbitmq::service
+ ##
+ describe 'service with default params' do
+ it { should contain_service('rabbitmq-server').with(
+ 'ensure' => 'running',
+ 'enable' => 'true',
+ 'hasstatus' => 'true',
+ 'hasrestart' => 'true'
+ )}
+ end
+
+ describe 'service with ensure stopped' do
+ let :params do
+ { :service_ensure => 'stopped' }
+ end
+
+ it { should contain_service('rabbitmq-server').with(
+ 'ensure' => 'stopped',
+ 'enable' => false
+ ) }
+ end
+
+ describe 'service with ensure neither running neither stopped' do
+ let :params do
+ { :service_ensure => 'foo' }
+ end
+
+ it 'should raise an error' do
+ expect {
+ should contain_service('rabbitmq-server').with(
+ 'ensure' => 'stopped' )
+ }.to raise_error(Puppet::Error, /validate_re\(\): "foo" does not match "\^\(running\|stopped\)\$"/)
+ end
+ end
+
+ describe 'service with service_manage equal to false' do
+ let :params do
+ { :service_manage => false }
+ end
+
+ it { should_not contain_service('rabbitmq-server') }
+ end
+
+ end
+ end
+
+ ##
+ ## rabbitmq::install
+ ##
+ context "on RHEL" do
+ let(:facts) {{ :osfamily => 'RedHat' }}
+ let(:params) {{ :package_source => 'http://www.rabbitmq.com/releases/rabbitmq-server/v3.2.3/rabbitmq-server-3.2.3-1.noarch.rpm' }}
+ it 'installs the rabbitmq package' do
+ should contain_package('rabbitmq-server').with(
+ 'ensure' => 'installed',
+ 'name' => 'rabbitmq-server',
+ 'provider' => 'rpm',
+ 'source' => 'http://www.rabbitmq.com/releases/rabbitmq-server/v3.2.3/rabbitmq-server-3.2.3-1.noarch.rpm'
+ )
+ end
+ end
+
+ context "on Debian" do
+ let(:facts) {{ :osfamily => 'Debian', :lsbdistid => 'Debian', :lsbdistcodename => 'precise' }}
+ it 'installs the rabbitmq package' do
+ should contain_package('rabbitmq-server').with(
+ 'ensure' => 'installed',
+ 'name' => 'rabbitmq-server',
+ 'provider' => 'apt'
+ )
+ end
+ end
+
+ context "on Archlinux" do
+ let(:facts) {{ :osfamily => 'Archlinux' }}
+ it 'installs the rabbitmq package' do
+ should contain_package('rabbitmq-server').with(
+ 'ensure' => 'installed',
+ 'name' => 'rabbitmq')
+ end
+ end
+
+ describe 'repo management on Debian' do
+ let(:facts) {{ :osfamily => 'Debian', :lsbdistid => 'Debian' }}
+
+ context 'with no pin' do
+ let(:params) {{ :package_apt_pin => '' }}
+ describe 'it sets up an apt::source' do
+
+ it { should contain_apt__source('rabbitmq').with(
+ 'location' => 'http://www.rabbitmq.com/debian/',
+ 'release' => 'testing',
+ 'repos' => 'main',
+ 'include_src' => false,
+ 'key' => 'F78372A06FF50C80464FC1B4F7B8CEA6056E8E56'
+ ) }
+ end
+ end
+
+ context 'with pin' do
+ let(:params) {{ :package_apt_pin => '700' }}
+ describe 'it sets up an apt::source and pin' do
+
+ it { should contain_apt__source('rabbitmq').with(
+ 'location' => 'http://www.rabbitmq.com/debian/',
+ 'release' => 'testing',
+ 'repos' => 'main',
+ 'include_src' => false,
+ 'key' => 'F78372A06FF50C80464FC1B4F7B8CEA6056E8E56'
+ ) }
+
+ it { should contain_apt__pin('rabbitmq').with(
+ 'packages' => 'rabbitmq-server',
+ 'priority' => '700'
+ ) }
+
+ end
+ end
+ end
+
+ ['RedHat', 'SuSE'].each do |distro|
+ describe "repo management on #{distro}" do
+ describe 'imports the key' do
+ let(:facts) {{ :osfamily => distro }}
+ let(:params) {{ :package_gpg_key => 'http://www.rabbitmq.com/rabbitmq-signing-key-public.asc' }}
+
+ it { should contain_exec("rpm --import #{params[:package_gpg_key]}").with(
+ 'path' => ['/bin','/usr/bin','/sbin','/usr/sbin']
+ ) }
+ end
+ end
+ end
+
+end
--- /dev/null
+--format
+s
+--colour
+--loadby
+mtime
+--backtrace
--- /dev/null
+require 'puppetlabs_spec_helper/module_spec_helper'
--- /dev/null
+require 'beaker-rspec'
+
+UNSUPPORTED_PLATFORMS = []
+
+unless ENV['RS_PROVISION'] == 'no' or ENV['BEAKER_provision'] == 'no'
+ if hosts.first.is_pe?
+ install_pe
+ else
+ install_puppet
+ end
+ hosts.each do |host|
+ on hosts, "mkdir -p #{host['distmoduledir']}"
+ end
+end
+
+RSpec.configure do |c|
+ # Project root
+ proj_root = File.expand_path(File.join(File.dirname(__FILE__), '..'))
+
+ # Readable test descriptions
+ c.formatter = :documentation
+ c.before :suite do
+ 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] })
+ if fact('osfamily') == 'Debian'
+ shell('puppet module install puppetlabs-apt --version 1.8.0 --force', { :acceptable_exit_codes => [0,1] })
+ end
+ shell('puppet module install nanliu-staging', { :acceptable_exit_codes => [0,1] })
+ if fact('osfamily') == 'RedHat'
+ shell('puppet module install garethr-erlang', { :acceptable_exit_codes => [0,1] })
+ end
+ end
+ end
+end
+
--- /dev/null
+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', '-c', '/etc/rabbitmq/rabbitmqadmin.conf', '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', '-c', '/etc/rabbitmq/rabbitmqadmin.conf', 'source=source', 'destination_type=queue', 'destination=target', 'properties_key=blablub')
+ @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', '-c', '/etc/rabbitmq/rabbitmqadmin.conf', 'source=source', 'destination=test2', 'arguments={}', 'routing_key=blablubd', 'destination_type=queue')
+ @provider.create
+ end
+ end
+end
--- /dev/null
+require 'puppet'
+require 'mocha'
+RSpec.configure do |config|
+ config.mock_with :mocha
+end
+provider_class = Puppet::Type.type(:rabbitmq_exchange).provider(:rabbitmqadmin)
+describe provider_class do
+ before :each do
+ @resource = Puppet::Type::Rabbitmq_exchange.new(
+ {:name => 'test.headers@/',
+ :type => :headers,
+ :internal => :false,
+ :durable => :true,
+ :auto_delete => :false,
+ :arguments => {
+ "hash-headers" => "message-distribution-hash"
+ },
+ }
+ )
+ @provider = provider_class.new(@resource)
+ end
+
+ it 'should return instances' do
+ provider_class.expects(:rabbitmqctl).with('-q', 'list_vhosts').returns <<-EOT
+/
+EOT
+ provider_class.expects(:rabbitmqctl).with('-q', 'list_exchanges', '-p', '/', 'name', 'type', 'internal', 'durable', 'auto_delete', 'arguments').returns <<-EOT
+ direct false true false []
+amq.direct direct false true false []
+amq.fanout fanout false true false []
+amq.headers headers false true false []
+amq.match headers false true false []
+amq.rabbitmq.log topic true true false []
+amq.rabbitmq.trace topic true true false []
+amq.topic topic false true false []
+test.headers x-consistent-hash false true false [{"hash-header","message-distribution-hash"}]
+EOT
+ instances = provider_class.instances
+ instances.size.should == 9
+ end
+
+ it 'should call rabbitmqadmin to create as guest' do
+ @provider.expects(:rabbitmqadmin).with('declare', 'exchange', '--vhost=/', '--user=guest', '--password=guest', 'name=test.headers', 'type=headers', 'internal=false', 'durable=true', 'auto_delete=false', 'arguments={"hash-headers":"message-distribution-hash"}', '-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=test.headers', '-c', '/etc/rabbitmq/rabbitmqadmin.conf')
+ @provider.destroy
+ end
+
+ context 'specifying credentials' do
+ before :each do
+ @resource = Puppet::Type::Rabbitmq_exchange.new(
+ {:name => 'test.headers@/',
+ :type => :headers,
+ :internal => 'false',
+ :durable => 'true',
+ :auto_delete => 'false',
+ :user => 'colin',
+ :password => 'secret',
+ :arguments => {
+ "hash-header" => "message-distribution-hash"
+ },
+ }
+ )
+ @provider = provider_class.new(@resource)
+ end
+
+ it 'should call rabbitmqadmin to create with credentials' do
+ @provider.expects(:rabbitmqadmin).with('declare', 'exchange', '--vhost=/', '--user=colin', '--password=secret', 'name=test.headers', 'type=headers', 'internal=false', 'durable=true', 'auto_delete=false', 'arguments={"hash-header":"message-distribution-hash"}', '-c', '/etc/rabbitmq/rabbitmqadmin.conf')
+ @provider.create
+ end
+ end
+end
--- /dev/null
+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
--- /dev/null
+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
--- /dev/null
+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', '-c', '/etc/rabbitmq/rabbitmqadmin.conf', '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', '-c', '/etc/rabbitmq/rabbitmqadmin.conf', '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', '-c', '/etc/rabbitmq/rabbitmqadmin.conf', 'name=test', 'durable=true', 'auto_delete=false', 'arguments={}')
+ @provider.create
+ end
+ end
+end
--- /dev/null
+require 'puppet'
+require 'mocha'
+RSpec.configure do |config|
+ config.mock_with :mocha
+end
+provider_class = Puppet::Type.type(:rabbitmq_user).provider(:rabbitmqctl)
+describe provider_class do
+ before :each do
+ @resource = Puppet::Type::Rabbitmq_user.new(
+ {:name => 'foo', :password => 'bar'}
+ )
+ @provider = provider_class.new(@resource)
+ end
+ it 'should match user names' do
+ @provider.expects(:rabbitmqctl).with('-q', 'list_users').returns <<-EOT
+foo
+EOT
+ @provider.exists?.should == 'foo'
+ end
+ it 'should match user names with 2.4.1 syntax' do
+ @provider.expects(:rabbitmqctl).with('-q', 'list_users').returns <<-EOT
+foo bar
+EOT
+ @provider.exists?.should == 'foo bar'
+ end
+ it 'should not match if no users on system' do
+ @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('-q', 'list_users').returns <<-EOT
+fooey
+EOT
+ @provider.exists?.should be_nil
+ end
+ it 'should match user names from list' do
+ @provider.expects(:rabbitmqctl).with('-q', 'list_users').returns <<-EOT
+one
+two three
+foo
+bar
+EOT
+ @provider.exists?.should == 'foo'
+ end
+ it 'should create user and set password' do
+ @resource[:password] = 'bar'
+ @provider.expects(:rabbitmqctl).with('add_user', 'foo', 'bar')
+ @provider.create
+ end
+ it 'should create user, set password and set to admin' do
+ @resource[:password] = 'bar'
+ @resource[:admin] = 'true'
+ @provider.expects(:rabbitmqctl).with('add_user', 'foo', 'bar')
+ @provider.expects(:rabbitmqctl).with('-q', 'list_users').returns <<-EOT
+foo []
+icinga [monitoring]
+kitchen []
+kitchen2 [abc, def, ghi]
+EOT
+ @provider.expects(:rabbitmqctl).with('set_user_tags', 'foo', ['administrator'])
+ @provider.create
+ end
+ it 'should call rabbitmqctl to delete' do
+ @provider.expects(:rabbitmqctl).with('delete_user', 'foo')
+ @provider.destroy
+ end
+ it 'should be able to retrieve admin value' do
+ @provider.expects(:rabbitmqctl).with('-q', 'list_users').returns <<-EOT
+foo [administrator]
+EOT
+ @provider.admin.should == :true
+ @provider.expects(:rabbitmqctl).with('-q', 'list_users').returns <<-EOT
+one [administrator]
+foo []
+EOT
+ @provider.admin.should == :false
+ end
+ it 'should fail if admin value is invalid' do
+ @provider.expects(:rabbitmqctl).with('-q', 'list_users').returns <<-EOT
+foo fail
+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('-q', 'list_users').returns <<-EOT
+foo []
+icinga [monitoring]
+kitchen []
+kitchen2 [abc, def, ghi]
+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('-q', 'list_users').returns <<-EOT
+foo [bar, baz]
+icinga [monitoring]
+kitchen []
+kitchen2 [abc, def, ghi]
+EOT
+ @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('-q', 'list_users').returns <<-EOT
+foo [administrator]
+guest [administrator]
+icinga []
+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('-q', 'list_users').returns <<-EOT
+foo [administrator, bar, baz]
+icinga [monitoring]
+kitchen []
+kitchen2 [abc, def, ghi]
+EOT
+ @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('-q', 'list_users').returns <<-EOT
+one [administrator]
+foo [tag1,tag2]
+icinga [monitoring]
+kitchen []
+kitchen2 [abc, def, ghi]
+EOT
+ @provider.expects(:rabbitmqctl).with('set_user_tags', 'foo', [])
+ @provider.tags=[]
+ end
+
+ it 'should set multiple tags' do
+ @provider.expects(:rabbitmqctl).with('-q', 'list_users').returns <<-EOT
+one [administrator]
+foo []
+icinga [monitoring]
+kitchen []
+kitchen2 [abc, def, ghi]
+EOT
+ @provider.expects(:rabbitmqctl).with('set_user_tags', 'foo', ['tag1','tag2'])
+ @provider.tags=['tag1','tag2']
+ end
+
+ it 'should clear tags while keep admin tag' do
+ @resource[:admin] = true
+ @provider.expects(:rabbitmqctl).with('-q', 'list_users').returns <<-EOT
+one [administrator]
+foo [administrator, tag1, tag2]
+icinga [monitoring]
+kitchen []
+kitchen2 [abc, def, ghi]
+EOT
+ @provider.expects(:rabbitmqctl).with('set_user_tags', 'foo', ["administrator"])
+ @provider.tags=[]
+ end
+
+ it 'should change tags while keep admin tag' do
+ @resource[:admin] = true
+ @provider.expects(:rabbitmqctl).with('-q', 'list_users').returns <<-EOT
+one [administrator]
+foo [administrator, tag1, tag2]
+icinga [monitoring]
+kitchen []
+kitchen2 [abc, def, ghi]
+EOT
+ @provider.expects(:rabbitmqctl).with('set_user_tags', 'foo', ["administrator","tag1","tag3","tag7"])
+ @provider.tags=['tag1','tag7','tag3']
+ end
+
+ it 'should create user with tags and without admin' do
+ @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('-q', 'list_users').returns <<-EOT
+foo []
+EOT
+ @provider.create
+ end
+
+ it 'should create user with tags and with admin' do
+ @resource[:tags] = [ "tag1", "tag2" ]
+ @resource[:admin] = true
+ @provider.expects(:rabbitmqctl).with('add_user', 'foo', 'bar')
+ @provider.expects(:rabbitmqctl).with('-q', 'list_users').twice.returns <<-EOT
+foo []
+EOT
+ @provider.expects(:rabbitmqctl).with('set_user_tags', 'foo', ["administrator"])
+ @provider.expects(:rabbitmqctl).with('set_user_tags', 'foo', ["administrator","tag1","tag2"])
+ @provider.create
+ end
+
+ it 'should not return the administrator tag in tags for admins' do
+ @resource[:tags] = []
+ @resource[:admin] = true
+ @provider.expects(:rabbitmqctl).with('-q', 'list_users').returns <<-EOT
+foo [administrator]
+EOT
+ @provider.tags.should == []
+ end
+
+ it 'should return the administrator tag for non-admins' do
+ # this should not happen though.
+ @resource[:tags] = []
+ @resource[:admin] = :false
+ @provider.expects(:rabbitmqctl).with('-q', 'list_users').returns <<-EOT
+foo [administrator]
+EOT
+ @provider.tags.should == ["administrator"]
+ end
+end
--- /dev/null
+require 'puppet'
+require 'mocha'
+RSpec.configure do |config|
+ config.mock_with :mocha
+end
+describe 'Puppet::Type.type(:rabbitmq_user_permissions).provider(:rabbitmqctl)' do
+ before :each do
+ @provider_class = Puppet::Type.type(:rabbitmq_user_permissions).provider(:rabbitmqctl)
+ @resource = Puppet::Type::Rabbitmq_user_permissions.new(
+ {:name => 'foo@bar'}
+ )
+ @provider = @provider_class.new(@resource)
+ end
+ after :each do
+ @provider_class.instance_variable_set(:@users, nil)
+ end
+ it 'should match user permissions from list' do
+ @provider.class.expects(:rabbitmqctl).with('-q', 'list_user_permissions', 'foo').returns <<-EOT
+bar 1 2 3
+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('-q', 'list_user_permissions', 'foo').returns <<-EOT
+bar 3
+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('-q', 'list_user_permissions', 'foo').returns <<-EOT
+bar 1 2 3 4
+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('-q', 'list_user_permissions', 'foo').returns <<-EOT
+EOT
+ @provider.exists?.should == nil
+ end
+ it 'should create default permissions' do
+ @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
+ 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
+ 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('-q', 'list_user_permissions', 'foo').returns <<-EOT
+bar 1 2 3
+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('-q', 'list_user_permissions', 'foo').returns <<-EOT
+bar 1 2 3
+EOT
+ @provider.exists?
+ @provider.send(k).should == v
+ end
+ end
+ {:configure_permission => ['foo', '2', '3'],
+ :read_permission => ['1', '2', 'foo'],
+ :write_permission => ['1', 'foo', '3']
+ }.each do |perm, columns|
+ it "should be able to sync #{perm}" do
+ @provider.class.expects(:rabbitmqctl).with('-q', 'list_user_permissions', 'foo').returns <<-EOT
+bar 1 2 3
+EOT
+ @provider.resource[perm] = 'foo'
+ @provider.expects(:rabbitmqctl).with('set_permissions', '-p', 'bar', 'foo', *columns)
+ @provider.send("#{perm}=".to_sym, 'foo')
+ end
+ end
+ it 'should only call set_permissions once' do
+ @provider.class.expects(:rabbitmqctl).with('-q', 'list_user_permissions', 'foo').returns <<-EOT
+bar 1 2 3
+EOT
+ @provider.resource[:configure_permission] = 'foo'
+ @provider.resource[:read_permission] = 'foo'
+ @provider.expects(:rabbitmqctl).with('set_permissions', '-p', 'bar', 'foo', 'foo', '2', 'foo').once
+ @provider.configure_permission='foo'
+ @provider.read_permission='foo'
+ end
+end
+
--- /dev/null
+require 'puppet'
+require 'mocha'
+RSpec.configure do |config|
+ config.mock_with :mocha
+end
+provider_class = Puppet::Type.type(:rabbitmq_vhost).provider(:rabbitmqctl)
+describe provider_class do
+ before :each do
+ @resource = Puppet::Type::Rabbitmq_vhost.new(
+ {:name => 'foo'}
+ )
+ @provider = provider_class.new(@resource)
+ end
+ it 'should match vhost names' do
+ @provider.expects(:rabbitmqctl).with('-q', 'list_vhosts').returns <<-EOT
+Listing vhosts ...
+foo
+...done.
+EOT
+ @provider.exists?.should == 'foo'
+ end
+ it 'should not match if no vhosts on system' do
+ @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('-q', 'list_vhosts').returns <<-EOT
+Listing vhosts ...
+fooey
+...done.
+EOT
+ @provider.exists?.should be_nil
+ end
+ it 'should call rabbitmqctl to create' do
+ @provider.expects(:rabbitmqctl).with('add_vhost', 'foo')
+ @provider.create
+ end
+ it 'should call rabbitmqctl to create' do
+ @provider.expects(:rabbitmqctl).with('delete_vhost', 'foo')
+ @provider.destroy
+ end
+end
--- /dev/null
+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
--- /dev/null
+require 'puppet'
+require 'puppet/type/rabbitmq_exchange'
+describe Puppet::Type.type(:rabbitmq_exchange) do
+ before :each do
+ @exchange = Puppet::Type.type(:rabbitmq_exchange).new(
+ :name => 'foo@bar',
+ :type => :topic,
+ :internal => false,
+ :auto_delete => false,
+ :durable => true
+ )
+ end
+ it 'should accept an exchange name' do
+ @exchange[:name] = 'dan@pl'
+ @exchange[:name].should == 'dan@pl'
+ end
+ it 'should require a name' do
+ expect {
+ Puppet::Type.type(:rabbitmq_exchange).new({})
+ }.to raise_error(Puppet::Error, 'Title or name must be provided')
+ end
+ it 'should not allow whitespace in the name' do
+ expect {
+ @exchange[:name] = 'b r'
+ }.to raise_error(Puppet::Error, /Valid values match/)
+ end
+ it 'should not allow names without @' do
+ expect {
+ @exchange[:name] = 'b_r'
+ }.to raise_error(Puppet::Error, /Valid values match/)
+ end
+
+ it 'should accept an exchange type' do
+ @exchange[:type] = :direct
+ @exchange[:type].should == :direct
+ end
+ it 'should require a type' do
+ expect {
+ Puppet::Type.type(:rabbitmq_exchange).new(:name => 'foo@bar')
+ }.to raise_error(/.*must set type when creating exchange.*/)
+ end
+ it 'should not require a type when destroying' do
+ expect {
+ Puppet::Type.type(:rabbitmq_exchange).new(:name => 'foo@bar', :ensure => :absent)
+ }.to_not raise_error
+ end
+
+ it 'should accept a user' do
+ @exchange[:user] = :root
+ @exchange[:user].should == :root
+ end
+
+ it 'should accept a password' do
+ @exchange[:password] = :PaSsw0rD
+ @exchange[:password].should == :PaSsw0rD
+ end
+end
--- /dev/null
+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
+
+ it 'should accept and convert ha-params for ha-mode exactly' do
+ definition = {'ha-mode' => 'exactly', 'ha-params' => '2'}
+ @policy[:definition] = definition
+ @policy[:definition]['ha-params'].should be_a(Fixnum)
+ @policy[:definition]['ha-params'].should == 2
+ end
+
+ it 'should not accept non-numeric ha-params for ha-mode exactly' do
+ definition = {'ha-mode' => 'exactly', 'ha-params' => 'nonnumeric'}
+ expect {
+ @policy[:definition] = definition
+ }.to raise_error(Puppet::Error, /Invalid ha-params.*nonnumeric.*exactly/)
+ end
+
+ it 'should accept and convert the expires value' do
+ definition = {'expires' => '1800000'}
+ @policy[:definition] = definition
+ @policy[:definition]['expires'].should be_a(Fixnum)
+ @policy[:definition]['expires'].should == 1800000
+ end
+
+ it 'should not accept non-numeric expires value' do
+ definition = {'expires' => 'future'}
+ expect {
+ @policy[:definition] = definition
+ }.to raise_error(Puppet::Error, /Invalid expires value.*future/)
+ end
+end
--- /dev/null
+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
--- /dev/null
+require 'puppet'
+require 'puppet/type/rabbitmq_user_permissions'
+describe Puppet::Type.type(:rabbitmq_user_permissions) do
+ before :each do
+ @perms = Puppet::Type.type(:rabbitmq_user_permissions).new(:name => 'foo@bar')
+ end
+ it 'should accept a valid hostname name' do
+ @perms[:name] = 'dan@bar'
+ @perms[:name].should == 'dan@bar'
+ end
+ it 'should require a name' do
+ expect {
+ Puppet::Type.type(:rabbitmq_user_permissions).new({})
+ }.to raise_error(Puppet::Error, 'Title or name must be provided')
+ end
+ it 'should fail when names dont have a @' do
+ expect {
+ @perms[:name] = 'bar'
+ }.to raise_error(Puppet::Error, /Valid values match/)
+ end
+ [:configure_permission, :read_permission, :write_permission].each do |param|
+ it 'should not default to anything' do
+ @perms[param].should == nil
+ end
+ it "should accept a valid regex for #{param}" do
+ @perms[param] = '.*?'
+ @perms[param].should == '.*?'
+ end
+ it "should accept an empty string for #{param}" do
+ @perms[param] = ''
+ @perms[param].should == ''
+ end
+ it "should not accept invalid regex for #{param}" do
+ expect {
+ @perms[param] = '*'
+ }.to raise_error(Puppet::Error, /Invalid regexp/)
+ end
+ end
+ {:rabbitmq_vhost => 'dan@test', :rabbitmq_user => 'test@dan'}.each do |k,v|
+ it "should autorequire #{k}" do
+ if k == :rabbitmq_vhost
+ vhost = Puppet::Type.type(k).new(:name => "test")
+ else
+ vhost = Puppet::Type.type(k).new(:name => "test", :password => 'pass')
+ end
+ perm = Puppet::Type.type(:rabbitmq_user_permissions).new(:name => v)
+ config = Puppet::Resource::Catalog.new :testing do |conf|
+ [vhost, perm].each { |resource| conf.add_resource resource }
+ end
+ rel = perm.autorequire[0]
+ rel.source.ref.should == vhost.ref
+ rel.target.ref.should == perm.ref
+ end
+ end
+end
--- /dev/null
+require 'puppet'
+require 'puppet/type/rabbitmq_user'
+describe Puppet::Type.type(:rabbitmq_user) do
+ before :each do
+ @user = Puppet::Type.type(:rabbitmq_user).new(:name => 'foo', :password => 'pass')
+ end
+ it 'should accept a user name' do
+ @user[:name] = 'dan'
+ @user[:name].should == 'dan'
+ @user[:admin].should == :false
+ end
+ it 'should accept a password' do
+ @user[:password] = 'foo'
+ @user[:password].should == 'foo'
+ end
+ it 'should require a password' do
+ expect {
+ Puppet::Type.type(:rabbitmq_user).new(:name => 'foo')
+ }.to raise_error(/must set password/)
+ end
+ it 'should require a name' do
+ expect {
+ Puppet::Type.type(:rabbitmq_user).new({})
+ }.to raise_error(Puppet::Error, 'Title or name must be provided')
+ end
+ it 'should not allow whitespace in the name' do
+ expect {
+ @user[:name] = 'b r'
+ }.to raise_error(Puppet::Error, /Valid values match/)
+ end
+ [true, false, 'true', 'false'].each do |val|
+ it "admin property should accept #{val}" do
+ @user[:admin] = val
+ @user[:admin].should == val.to_s.to_sym
+ end
+ end
+ it 'should not accept non-boolean values for admin' do
+ expect {
+ @user[:admin] = 'yes'
+ }.to raise_error(Puppet::Error, /Invalid value/)
+ end
+ it 'should not accept tags with spaces' do
+ expect {
+ @user[:tags] = ['policy maker']
+ }.to raise_error(Puppet::Error, /Invalid tag/)
+ end
+ it 'should not accept the administrator tag' do
+ expect {
+ @user[:tags] = ['administrator']
+ }.to raise_error(Puppet::Error, /must use admin property/)
+ end
+end
--- /dev/null
+require 'puppet'
+require 'puppet/type/rabbitmq_vhost'
+describe Puppet::Type.type(:rabbitmq_vhost) do
+ before :each do
+ @vhost = Puppet::Type.type(:rabbitmq_vhost).new(:name => 'foo')
+ end
+ it 'should accept a vhost name' do
+ @vhost[:name] = 'dan'
+ @vhost[:name].should == 'dan'
+ end
+ it 'should require a name' do
+ expect {
+ Puppet::Type.type(:rabbitmq_vhost).new({})
+ }.to raise_error(Puppet::Error, 'Title or name must be provided')
+ end
+ it 'should not allow whitespace in the name' do
+ expect {
+ @vhost[:name] = 'b r'
+ }.to raise_error(Puppet::Error, /Valid values match/)
+ end
+end
--- /dev/null
+Templates
+=========
+
+Puppet supports templates and templating via ERB, which is part of the Ruby
+standard library and is used for many other projects including Ruby on Rails.
+Templates allow you to manage the content of template files, for example
+configuration files that cannot yet be managed as a Puppet type. Learn more at
+http://projects.puppetlabs.com/projects/puppet/wiki/Puppet_Templating
+
+You can use templates like this:
+
+ class myclass {
+ package { mypackage: ensure => latest }
+ service { myservice: ensure => running }
+ file { "/etc/myfile":
+ content => template("mymodule/myfile.erb")
+ }
+ }
+
+The templates are searched for in:
+
+ $templatedir/mymodule/myfile.erb
+ $modulepath/mymodule/templates/myfile.erb
--- /dev/null
+# File managed by Puppet.
+
+# This file is sourced by /etc/init.d/rabbitmq-server. Its primary
+# reason for existing is to allow adjustment of system limits for the
+# rabbitmq-server process.
+#
+# Maximum number of open file handles. This will need to be increased
+# to handle many simultaneous connections. Refer to the system
+# documentation for ulimit (in man bash) for more information.
+ulimit -n <%= @file_limit %>
--- /dev/null
+rabbitmq soft nofile <%= @file_limit %>
+rabbitmq hard nofile <%= @file_limit %>
--- /dev/null
+<%- @environment_variables.keys.sort.each do |key| -%>
+<%- if @environment_variables[key] != 'UNSET' -%>
+<%= key %>=<%= @environment_variables[key] %>
+<%- end -%>
+<%- end -%>
--- /dev/null
+[Service]
+LimitNOFILE=<%= @file_limit %>
--- /dev/null
+% 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, {[<%= @cluster_nodes.map { |n| "\'rabbit@#{n}\'" }.join(', ') %>], <%= @cluster_node_type %>}},
+ {cluster_partition_handling, <%= @cluster_partition_handling %>},
+<% end -%>
+<%- if @tcp_keepalive -%>
+ {tcp_listen_options, [{keepalive, true}]},
+<%- end -%>
+<%- if @ssl_only -%>
+ {tcp_listeners, []},
+<%- elsif @interface != 'UNSET' -%>
+ {tcp_listeners, [{"<%= @interface%>", <%= @port %>}]},
+<%- end -%>
+<%- if @ssl -%>
+ <%- if @ssl_interface != 'UNSET' -%>
+ {ssl_listeners, [{"<%= @ssl_interface%>", <%= @ssl_port %>}]},
+ <%- else -%>
+ {ssl_listeners, [<%= @ssl_port %>]},
+ <%- end -%>
+ {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 %>}
+ <%- if @ssl_versions -%>
+ ,{versions, [<%= @ssl_versions.sort.map { |v| "'#{v}'" }.join(', ') %>]}
+ <%- end -%>
+ <%- if @ssl_ciphers and @ssl_ciphers.size > 0 -%>
+ ,{ciphers,[
+ <%= @ssl_ciphers.sort.map{|k| "{#{k}}"}.join(",\n ") %>
+ ]}
+ <%- end -%>
+ ]},
+<%- end -%>
+<% if @config_variables -%>
+<%- @config_variables.keys.sort.each do |key| -%>
+ {<%= key %>, <%= @config_variables[key] %>},
+<%- end -%>
+<%- end -%>
+ {default_user, <<"<%= @default_user %>">>},
+ {default_pass, <<"<%= @default_pass %>">>}
+ ]}<% if @config_kernel_variables -%>,
+ {kernel, [
+ <%= @config_kernel_variables.sort.map{|k,v| "{#{k}, #{v}}"}.join(",\n ") %>
+ ]}
+<%- end -%>
+<%- if @admin_enable -%>,
+ {rabbitmq_management, [
+ {listener, [
+<%- if @ssl -%>
+ {port, <%= @ssl_management_port %>},
+ {ssl, true},
+ {ssl_opts, [<%- if @ssl_cacert != 'UNSET' -%>{cacertfile, "<%= @ssl_cacert %>"},<%- end -%>
+
+ {certfile, "<%= @ssl_cert %>"},
+ {keyfile, "<%= @ssl_key %>"}
+ <%- if @ssl_versions -%>
+ ,{versions, [<%= @ssl_versions.sort.map { |v| "'#{v}'" }.join(', ') %>]}
+ <%- end -%>
+ <%- if @ssl_ciphers and @ssl_ciphers.size > 0 -%>
+ ,{ciphers,[
+ <%= @ssl_ciphers.sort.map{|k| "{#{k}}"}.join(",\n ") %>
+ ]}
+ <%- end -%>
+ ]}
+<%- else -%>
+ {port, <%= @management_port %>}
+<%- end -%>
+ ]}
+ ]}
+<%- end -%>
+<% if @config_stomp -%>,
+% Configure the Stomp Plugin listening port
+ {rabbitmq_stomp, [
+ {tcp_listeners, [<%= @stomp_port %>]}
+ <%- if @ssl && @ssl_stomp_port -%>,
+ {ssl_listeners, [<%= @ssl_stomp_port %>]}
+ <%- end -%>
+ ]}
+<% end -%>
+<%- if @ldap_auth -%>,
+% Configure the LDAP authentication plugin
+ {rabbitmq_auth_backend_ldap, [
+ {other_bind, <%= @ldap_other_bind %>},
+ {servers, ["<%= @ldap_server %>"]},
+ {user_dn_pattern, "<%= @ldap_user_dn_pattern %>"},
+ {use_ssl, <%= @ldap_use_ssl %>},
+ {port, <%= @ldap_port %>},
+<% if @ldap_config_variables -%>
+<%- @ldap_config_variables.keys.sort.each do |key| -%>
+ {<%= key %>, <%= @ldap_config_variables[key] %>},
+<%- end -%>
+<%- end -%>
+ {log, <%= @ldap_log %>}
+ ]}
+<%- end -%>
+].
+% EOF
--- /dev/null
+[default]
+<% if @ssl -%>
+ssl = True
+port = <%= @ssl_management_port %>
+<% else -%>
+port = <%= @management_port %>
+<% end -%>
--- /dev/null
+# install first the garethr-erlang module. See README.md
+include 'erlang'
+
+class { 'erlang': epel_enable => true}
+Class['erlang'] -> Class['rabbitmq']
--- /dev/null
+class { 'rabbitmq::repo::apt':
+ pin => '900',
+}->
+class { 'rabbitmq::server':
+ delete_guest_user => true,
+# version => '2.4.1',
+}->
+rabbitmq_user { 'dan':
+ admin => true,
+ password => 'pass',
+ provider => 'rabbitmqctl',
+}->
+rabbitmq_vhost { 'myhost':
+ provider => 'rabbitmqctl',
+}
+rabbitmq_user_permissions { 'dan@myhost':
+ configure_permission => '.*',
+ read_permission => '.*',
+ write_permission => '.*',
+ provider => 'rabbitmqctl',
+}
--- /dev/null
+rabbitmq_user { 'blah7':
+ password => 'foo',
+}
+rabbitmq_vhost { 'test5': }
+rabbitmq_user_permissions { 'blah7@test5':
+ configure_permission => 'config2',
+ read_permission => 'ready',
+ #write_permission => 'ready',
+}
--- /dev/null
+class { 'rabbitmq::server':
+ config_stomp => true,
+}
+
+$rabbitmq_plugins = [ 'amqp_client', 'rabbitmq_stomp' ]
+
+rabbitmq_plugin { $rabbitmq_plugins:
+ ensure => present,
+ require => Class['rabbitmq::server'],
+ provider => 'rabbitmqplugins',
+}
--- /dev/null
+# requires pupetlabs-apt
+include rabbitmq::repo::apt
--- /dev/null
+class { 'rabbitmq::server':
+ port => '5672',
+ delete_guest_user => true,
+ version => 'latest',
+}
--- /dev/null
+class { 'rabbitmq::service': }
--- /dev/null
+node default {
+
+ $rabbitmq_plugins = [ 'amqp_client', 'rabbitmq_stomp' ]
+
+ class { 'rabbitmq::server':
+ config => '[ {rabbit_stomp, [{tcp_listeners, [1234]} ]} ].',
+ }
+
+ # Required for MCollective
+ rabbitmq_plugin { $rabbitmq_plugins:
+ ensure => present,
+ require => Class['rabbitmq::server'],
+ provider => 'rabbitmqplugins',
+ }
+}
+
--- /dev/null
+rabbitmq_user { ['blah2', 'blah3', 'blah4']:
+ password => 'phoey!',
+ #provider => 'rabbitmqctl',
+}
--- /dev/null
+rabbitmq_vhost { ['fooey', 'blah']: }
+++ /dev/null
-Puppet::Type.type(:rabbitmq_plugin).provide(:default) do
-
- def self.instances
- []
- end
-
- def create
- default_fail
- end
-
- def destroy
- default_fail
- end
-
- def exists?
- default_fail
- end
-
- def default_fail
- fail('This is just the default provider for rabbitmq_plugin, all it does is fail')
- end
-end
+++ /dev/null
-Puppet::Type.type(:rabbitmq_plugin).provide(:rabbitmqplugins) do
-
- commands :rabbitmqplugins => '/usr/lib/rabbitmq/bin/rabbitmq-plugins'
- defaultfor :feature => :posix
-
- def self.instances
- rabbitmqplugins('list', '-E').split(/\n/).map do |line|
- if line.split(/\s+/)[1] =~ /^(\S+)$/
- new(:name => $1)
- else
- raise Puppet::Error, "Cannot parse invalid plugins line: #{line}"
- end
- end
- end
-
- def create
- rabbitmqplugins('enable', resource[:name])
- end
-
- def destroy
- rabbitmqplugins('disable', resource[:name])
- end
-
- def exists?
- out = rabbitmqplugins('list', '-E').split(/\n/).detect do |line|
- line.split(/\s+/)[1].match(/^#{resource[:name]}$/)
- end
- end
-
-end
+++ /dev/null
-Puppet::Type.type(:rabbitmq_policy).provide(:default) do
-
- def self.instances
- []
- end
-
- def create
- default_fail
- end
-
- def destroy
- default_fail
- end
-
- def exists?
- default_fail
- end
-
- def default_fail
- fail('This is just the default provider for rabbitmq_policy, all it does is fail')
- end
-end
-
+++ /dev/null
-require 'puppet'
-Puppet::Type.type(:rabbitmq_policy).provide(:rabbitmqctl) do
-
- commands :rabbitmqctl => 'rabbitmqctl'
- defaultfor :feature => :posix
-
- def should_vhost
- if @should_vhost
- @should_vhost
- else
- @should_vhost = resource[:vhost]
- end
- end
-
- def self.instances
- rabbitmqctl('list_policies', '-p', should_vhost).split(/\n/)[1..-2].detect do |line|
- if line =~ /^(\S+)\s+(\S+)\s+(\S+)\s+(\S+)\s+.*$/
- new(:name => $2, :vhost => $1, :match => $3, :policy => $4)
- else
- raise Puppet::Error, "Cannot parse invalid user line: #{line}"
- end
- end
- end
-
- def create
- rabbitmqctl('set_policy', '-p', should_vhost, resource[:name], resource[:match], resource[:policy])
- end
-
- def destroy
- rabbitmqctl('clear_policy', '-p', should_vhost, resource[:name])
- end
-
- def exists?
- out = rabbitmqctl('list_policies', '-p', should_vhost).split(/\n/)[1..-2].detect do |line|
- line.match(/^\S+\s+#{resource[:name]}\s+\S+.*$/)
- end
- end
-
-end
+++ /dev/null
-Puppet::Type.type(:rabbitmq_user).provide(:default) do
-
- def self.instances
- []
- end
-
- def create
- default_fail
- end
-
- def destroy
- default_fail
- end
-
- def exists?
- default_fail
- end
-
- def default_fail
- fail('This is just the default provider for rabbitmq_user, all it does is fail')
- end
-end
+++ /dev/null
-require 'puppet'
-Puppet::Type.type(:rabbitmq_user).provide(:rabbitmqctl) do
-
- commands :rabbitmqctl => 'rabbitmqctl'
- defaultfor :feature => :posix
-
- def self.instances
- rabbitmqctl('list_users').split(/\n/)[1..-2].collect do |line|
- if line =~ /^(\S+)(\s+\S+|)$/
- new(:name => $1)
- else
- raise Puppet::Error, "Cannot parse invalid user line: #{line}"
- end
- end
- end
-
- def create
- rabbitmqctl('add_user', resource[:name], resource[:password])
- if resource[:admin] == :true
- make_user_admin()
- end
- end
-
- def destroy
- rabbitmqctl('delete_user', resource[:name])
- end
-
- def exists?
- out = rabbitmqctl('list_users').split(/\n/)[1..-2].detect do |line|
- line.match(/^#{resource[:name]}(\s+\S+|)$/)
- end
- end
-
- # def password
- # def password=()
- def admin
- match = rabbitmqctl('list_users').split(/\n/)[1..-2].collect do |line|
- line.match(/^#{resource[:name]}\s+\[(administrator)?\]/)
- end.compact.first
- if match
- (:true if match[1].to_s == 'administrator') || :false
- else
- raise Puppet::Error, "Could not match line '#{resource[:name]} (true|false)' from list_users (perhaps you are running on an older version of rabbitmq that does not support admin users?)"
- end
- end
-
- def admin=(state)
- if state == :true
- make_user_admin()
- else
- rabbitmqctl('set_user_tags', resource[:name])
- end
- end
-
- def make_user_admin
- rabbitmqctl('set_user_tags', resource[:name], 'administrator')
- end
-
-end
+++ /dev/null
-Puppet::Type.type(:rabbitmq_user_permissions).provide(:default) do
-
- def create
- default_fail
- end
-
- def destroy
- default_fail
- end
-
- def exists?
- default_fail
- end
-
- def default_fail
- fail('This is just the default provider for rabbitmq_user, all it does is fail')
- end
-end
+++ /dev/null
-Puppet::Type.type(:rabbitmq_user_permissions).provide(:rabbitmqctl) do
-
- commands :rabbitmqctl => 'rabbitmqctl'
- defaultfor :feature=> :posix
-
- #def self.instances
- #
- #end
-
- # cache users permissions
- def self.users(name, vhost)
- @users = {} unless @users
- unless @users[name]
- @users[name] = {}
- out = rabbitmqctl('list_user_permissions', name).split(/\n/)[1..-2].each do |line|
- if line =~ /^(\S+)\s+(\S+)\s+(\S+)\s+(\S+)$/
- @users[name][$1] =
- {:configure => $2, :read => $3, :write => $4}
- else
- raise Puppet::Error, "cannot parse line from list_user_permissions:#{line}"
- end
- end
- end
- @users[name][vhost]
- end
-
- def users(name, vhost)
- self.class.users(name, vhost)
- end
-
- def should_user
- if @should_user
- @should_user
- else
- @should_user = resource[:name].split('@')[0]
- end
- end
-
- def should_vhost
- if @should_vhost
- @should_vhost
- else
- @should_vhost = resource[:name].split('@')[1]
- end
- end
-
- def create
- resource[:configure_permission] ||= "'^$'"
- resource[:read_permission] ||= "'^$'"
- resource[:write_permission] ||= "'^$'"
- rabbitmqctl('set_permissions', '-p', should_vhost, should_user, resource[:configure_permission], resource[:read_permission], resource[:write_permission])
- end
-
- def destroy
- rabbitmqctl('clear_permissions', '-p', should_vhost, should_user)
- end
-
- # I am implementing prefetching in exists b/c I need to be sure
- # that the rabbitmq package is installed before I make this call.
- def exists?
- users(should_user, should_vhost)
- end
-
- def configure_permission
- users(should_user, should_vhost)[:configure]
- end
-
- def configure_permission=(perm)
- set_permissions
- end
-
- def read_permission
- users(should_user, should_vhost)[:read]
- end
-
- def read_permission=(perm)
- set_permissions
- end
-
- def write_permission
- users(should_user, should_vhost)[:write]
- end
-
- def write_permission=(perm)
- set_permissions
- end
-
- # implement memoization so that we only call set_permissions once
- def set_permissions
- unless @permissions_set
- @permissions_set = true
- resource[:configure_permission] ||= configure_permission
- resource[:read_permission] ||= read_permission
- resource[:write_permission] ||= write_permission
- rabbitmqctl('set_permissions', '-p', should_vhost, should_user,
- resource[:configure_permission], resource[:read_permission],
- resource[:write_permission]
- )
- end
- end
-
-end
+++ /dev/null
-Puppet::Type.type(:rabbitmq_vhost).provide(:default) do
-
- def self.instances
- []
- end
-
- def create
- default_fail
- end
-
- def destroy
- default_fail
- end
-
- def exists?
- default_fail
- end
-
- def default_fail
- fail('This is just the default provider for rabbitmq_vhost, all it does is fail')
- end
-end
+++ /dev/null
-Puppet::Type.type(:rabbitmq_vhost).provide(:rabbitmqctl) do
-
- commands :rabbitmqctl => 'rabbitmqctl'
- defaultfor :feature => :posix
-
- def self.instances
- rabbitmqctl('list_vhosts').split(/\n/)[1..-2].map do |line|
- if line =~ /^(\S+)$/
- new(:name => $1)
- else
- raise Puppet::Error, "Cannot parse invalid user line: #{line}"
- end
- end
- end
-
- def create
- rabbitmqctl('add_vhost', resource[:name])
- end
-
- def destroy
- rabbitmqctl('delete_vhost', resource[:name])
- end
-
- def exists?
- out = rabbitmqctl('list_vhosts').split(/\n/)[1..-2].detect do |line|
- line.match(/^#{resource[:name]}$/)
- end
- end
-
-end
+++ /dev/null
-Puppet::Type.newtype(:rabbitmq_plugin) do
- desc 'manages rabbitmq plugins'
-
- ensurable do
- defaultto(:present)
- newvalue(:present) do
- provider.create
- end
- newvalue(:absent) do
- provider.destroy
- end
- end
-
- newparam(:name, :namevar => true) do
- 'name of the plugin to enable'
- newvalues(/^\S+$/)
- end
-
-end
+++ /dev/null
-Puppet::Type.newtype(:rabbitmq_policy) do
- desc 'Native type for managing rabbitmq policy'
-
- 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 policy'
- newvalues(/^\S+$/)
- end
-
- newparam(:vhost) do
- desc 'Vhost for policy'
- newvalues(/^\S+$/)
- end
-
- newparam(:match) do
- desc 'Regex match for policy'
- end
-
- newparam(:policy) do
- desc 'Policy to set'
- end
-
- validate do
- if self[:ensure] == :present and ! self[:policy] and ! self[:match]
- raise ArgumentError, 'must set policy and match' unless self[:policy] and self[:match]
- end
- end
-
-end
-
+++ /dev/null
-Puppet::Type.newtype(:rabbitmq_user) do
- desc 'Native type for managing rabbitmq users'
-
- 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 user'
- newvalues(/^\S+$/)
- end
-
- # newproperty(:password) do
- newparam(:password) do
- desc 'User password to be set *on creation*'
- end
-
- newproperty(:admin) do
- desc 'rather or not user should be an admin'
- newvalues(/true|false/)
- munge do |value|
- # converting to_s incase its a boolean
- value.to_s.to_sym
- end
- defaultto :false
- end
-
- validate do
- if self[:ensure] == :present and ! self[:password]
- raise ArgumentError, 'must set password when creating user' unless self[:password]
- end
- end
-
-end
+++ /dev/null
-Puppet::Type.newtype(:rabbitmq_user_permissions) do
- desc 'Type for managing rabbitmq user permissions'
-
- ensurable do
- defaultto(:present)
- newvalue(:present) do
- provider.create
- end
- newvalue(:absent) do
- provider.destroy
- end
- end
-
- newparam(:name, :namevar => true) do
- 'combination of user@vhost to grant privileges to'
- newvalues(/^\S+@\S+$/)
- end
-
- newproperty(:configure_permission) do
- desc 'regexp representing configuration permissions'
- validate do |value|
- resource.validate_permissions(value)
- end
- end
-
- newproperty(:read_permission) do
- desc 'regexp representing read permissions'
- validate do |value|
- resource.validate_permissions(value)
- end
- end
-
- newproperty(:write_permission) do
- desc 'regexp representing write permissions'
- validate do |value|
- resource.validate_permissions(value)
- end
- end
-
- autorequire(:rabbitmq_vhost) do
- [self[:name].split('@')[1]]
- end
-
- autorequire(:rabbitmq_user) do
- [self[:name].split('@')[0]]
- end
-
- # I may want to dissalow whitespace
- def validate_permissions(value)
- begin
- Regexp.new(value)
- rescue RegexpError
- raise ArgumentError, "Invalid regexp #{value}"
- end
- end
-
-end
+++ /dev/null
-Puppet::Type.newtype(:rabbitmq_vhost) do
- desc 'manages rabbitmq vhosts'
-
- ensurable do
- defaultto(:present)
- newvalue(:present) do
- provider.create
- end
- newvalue(:absent) do
- provider.destroy
- end
- end
-
- newparam(:name, :namevar => true) do
- 'name of the vhost to add'
- newvalues(/^\S+$/)
- end
-
-end
+++ /dev/null
-# == Define: rabbitmq::autouser
-#
-# Create a user in rabbitmq automatically for debian.org hosts
-# Should automatically create a password
-#
-# === Parameters
-#
-# === Examples
-#
-# rabbitmq::autouser { 'master.debian.org': }
-#
-define rabbitmq::autouser () {
-
- $rabbit_password = hkdf('/etc/puppet/secret', "mq-client-${name}")
-
- rabbitmq_user { $name:
- admin => false,
- password => $rabbit_password,
- provider => 'rabbitmqctl',
- }
-
- rabbitmq_user_permissions { "${name}@dsa":
- configure_permission => '.*',
- read_permission => '.*',
- write_permission => '.*',
- provider => 'rabbitmqctl',
- require => [
- Rabbitmq_user[$name],
- Rabbitmq_vhost['dsa']
- ]
- }
-}
+++ /dev/null
-# == Class: rabbitmq::config
-#
-# Sets up the rabbitmq config file
-#
-class rabbitmq::config {
-
- concat { '/etc/rabbitmq/rabbitmq.config':
- require => Package['rabbitmq-server'],
- notify => Service['rabbitmq-server'],
- owner => root,
- group => $::root_group,
- mode => '0644',
- }
-}
+++ /dev/null
-# == Class: rabbitmq
-#
-# Top level class for all things rabbitmq
-#
-class rabbitmq (
- $cluster=false,
- $clustermembers=[],
- $clustercookie='',
- $delete_guest_user=false,
- $rabbit_num_ofiles=4096,
- $master=''
-) {
- include rabbitmq::config
-
- package { 'rabbitmq-server':
- ensure => installed,
- }
-
- service { 'rabbitmq-server':
- ensure => running,
- enable => true,
- require => Package['rabbitmq-server']
- }
-
- Service['rabbitmq-server'] -> Rabbitmq_user <| |>
- Service['rabbitmq-server'] -> Rabbitmq_vhost <| |>
- Service['rabbitmq-server'] -> Rabbitmq_user_permissions <| |>
-
- concat::fragment { 'rabbitmq_main_conf':
- target => '/etc/rabbitmq/rabbitmq.config',
- order => 00,
- content => template('rabbitmq/rabbitmq.conf.erb'),
- }
-
- concat::fragment { 'rabbit_foot':
- target => '/etc/rabbitmq/rabbitmq.config',
- order => 50,
- content => "]}\n"
- }
-
- concat::fragment { 'rabbitmq_conf_foot':
- target => '/etc/rabbitmq/rabbitmq.config',
- order => 99,
- content => "].\n"
- }
-
- file { '/etc/default/rabbitmq-server':
- content => template('rabbitmq/rabbitmq.ulimit.erb'),
- notify => Service['rabbitmq-server']
- }
-
- if $cluster {
- if $clustercookie {
- file { '/var/lib/rabbitmq':
- ensure => directory,
- mode => '0755',
- owner => rabbitmq,
- group => rabbitmq,
- }
-
- file { '/var/lib/rabbitmq/.erlang.cookie':
- content => $clustercookie,
- mode => '0500',
- owner => rabbitmq,
- group => rabbitmq,
- before => Package['rabbitmq-server'],
- notify => Service['rabbitmq-server']
- }
- }
-
- if $::hostname != $master {
- exec { 'reset_mq':
- command => 'rabbitmqctl stop_app && rabbitmqctl reset > /var/lib/rabbitmq/.node_reset',
- path => '/usr/bin:/bin:/usr/sbin:/sbin',
- creates => '/var/lib/rabbitmq/.node_reset',
- require => Package['rabbitmq-server'],
- notify => Service['rabbitmq-server']
- }
- Exec['reset_mq'] -> Rabbitmq_user <| |>
- Exec['reset_mq'] -> Rabbitmq_vhost <| |>
- Exec['reset_mq'] -> Rabbitmq_user_permissions <| |>
- }
- }
-
- if $delete_guest_user {
- rabbitmq_user { 'guest':
- ensure => absent,
- provider => 'rabbitmqctl',
- }
- }
-
- site::limit { 'rabbitmq_openfiles':
- limit_user => rabbitmq,
- limit_value => $rabbit_num_ofiles,
- notify => Service['rabbitmq-server']
- }
-}
+++ /dev/null
-[
-{rabbit, [
-<% if @cluster -%>
- {cluster_nodes, ['<%= @clustermembers.to_a.flatten.join("', '") %>']},
- {tcp_listen_options, [binary,
- {packet, raw},
- {reuseaddr, true},
- {backlog, 128},
- {nodelay, true},
- {exit_on_close, false},
- {keepalive, true}]}
-<% end -%>
+++ /dev/null
-ulimit -n <%= @rabbit_num_ofiles %>
+++ /dev/null
-,{rabbitmq_management,
- [{listener, [
- {port, 15672},
- {ssl, true},
- {ssl_opts, [
- {cacertfile,"/etc/ssl/debian/certs/ca.crt"},
- {certfile,"/etc/ssl/debian/certs/thishost-server.crt"},
- {keyfile,"/etc/ssl/debian/keys/thishost-server.key"}]}
- ]}
-]}
+++ /dev/null
- ,{ssl_listeners, [5671]},
- {ssl_options, [{cacertfile,"/etc/ssl/debian/certs/ca.crt"},
- {certfile,"/etc/ssl/debian/certs/thishost-server.crt"},
- {keyfile,"/etc/ssl/debian/keys/thishost-server.key"},
- {verify,verify_none},
- {fail_if_no_peer_cert,false}]}
-
$cc_secondary = rapoport
class { 'rabbitmq':
- cluster => true,
- clustermembers => [
+ config_cluster => true,
+ cluster_nodes => [
"rabbit@${cc_master}",
"rabbit@${cc_secondary}",
],
- clustercookie => '8r17so6o1s124ns49sr08n0o24342160',
+ cluster_node_type => 'disc',
+ erlang_cookie => '8r17so6o1s124ns49sr08n0o24342160',
delete_guest_user => true,
- master => $cc_master,
+ tcp_keepalive => true,
+ ssl_only => true,
+ ssl => true,
+ ssl_cacert => '/etc/ssl/debian/certs/ca.crt',
+ ssl_cert => '/etc/ssl/debian/certs/thishost-server.crt',
+ ssl_key => '/etc/ssl/debian/keys/thishost-server.key',
+ manage_repo => false,
}
user { 'rabbitmq':
groups => 'ssl-cert'
}
- concat::fragment { 'rabbit_ssl':
- target => '/etc/rabbitmq/rabbitmq.config',
- order => 35,
- source => 'puppet:///modules/roles/pubsub/rabbitmq.config'
- }
-
- concat::fragment { 'rabbit_mgmt_ssl':
- target => '/etc/rabbitmq/rabbitmq.config',
- order => 55,
- source => 'puppet:///modules/roles/pubsub/rabbitmq-mgmt.config'
- }
-
@ferm::rule { 'rabbitmq':
description => 'rabbitmq connections',
rule => '&SERVICE_RANGE(tcp, 5671, $HOST_DEBIAN_V4)'
rabbitmq_user { 'admin':
admin => true,
password => $admin_password,
- provider => 'rabbitmqctl',
}
rabbitmq_user { 'ftpteam':
admin => false,
password => $ftp_password,
- provider => 'rabbitmqctl',
}
rabbitmq_user { 'buildd':
admin => false,
password => $buildd_password,
- provider => 'rabbitmqctl',
}
rabbitmq_user { 'wbadm':
admin => false,
password => $wbadm_password,
- provider => 'rabbitmqctl',
}
rabbitmq_user { 'mailadm':
admin => false,
password => $mailadm_password,
- provider => 'rabbitmqctl',
}
rabbitmq_user { 'mailly':
admin => false,
password => $mailly_password,
- provider => 'rabbitmqctl',
}
rabbitmq_user { 'muffat':
admin => false,
password => $muffat_password,
- provider => 'rabbitmqctl',
}
rabbitmq_user { 'pet-devel':
admin => false,
password => $pet_password,
- provider => 'rabbitmqctl',
}
- $do_hosts = keys($site::localinfo)
-
- rabbitmq::autouser { $do_hosts: }
-
rabbitmq_vhost { 'packages':
ensure => present,
- provider => 'rabbitmqctl',
}
rabbitmq_vhost { 'buildd':
ensure => present,
- provider => 'rabbitmqctl',
}
rabbitmq_vhost { 'dsa':
ensure => present,
- provider => 'rabbitmqctl',
}
rabbitmq_vhost { 'pet':
ensure => present,
- provider => 'rabbitmqctl',
}
rabbitmq_user_permissions { 'admin@/':
configure_permission => '.*',
read_permission => '.*',
write_permission => '.*',
- provider => 'rabbitmqctl',
- require => Rabbitmq_user['admin']
}
rabbitmq_user_permissions { 'admin@buildd':
configure_permission => '.*',
read_permission => '.*',
write_permission => '.*',
- provider => 'rabbitmqctl',
- require => [
- Rabbitmq_user['admin'],
- Rabbitmq_vhost['buildd']
- ]
}
rabbitmq_user_permissions { 'admin@dsa':
configure_permission => '.*',
read_permission => '.*',
write_permission => '.*',
- provider => 'rabbitmqctl',
- require => [
- Rabbitmq_user['admin'],
- Rabbitmq_vhost['dsa']
- ]
}
rabbitmq_user_permissions { 'admin@packages':
configure_permission => '.*',
read_permission => '.*',
write_permission => '.*',
- provider => 'rabbitmqctl',
- require => [
- Rabbitmq_user['admin'],
- Rabbitmq_vhost['packages']
- ]
}
rabbitmq_user_permissions { 'admin@pet':
configure_permission => '.*',
read_permission => '.*',
write_permission => '.*',
- provider => 'rabbitmqctl',
- require => [
- Rabbitmq_user['admin'],
- Rabbitmq_vhost['pet']
- ]
}
rabbitmq_user_permissions { 'ftpteam@packages':
configure_permission => '.*',
read_permission => '.*',
write_permission => '.*',
- provider => 'rabbitmqctl',
- require => [
- Rabbitmq_user['ftpteam'],
- Rabbitmq_vhost['packages']
- ]
}
rabbitmq_user_permissions { 'wbadm@packages':
read_permission => 'unchecked',
write_permission => 'wbadm',
- provider => 'rabbitmqctl',
- require => [
- Rabbitmq_user['wbadm'],
- Rabbitmq_vhost['packages']
- ]
}
rabbitmq_user_permissions { 'buildd@buildd':
configure_permission => '.*',
read_permission => '.*',
write_permission => '.*',
- provider => 'rabbitmqctl',
- require => [
- Rabbitmq_user['buildd'],
- Rabbitmq_vhost['buildd']
- ]
}
rabbitmq_user_permissions { 'wbadm@buildd':
configure_permission => '.*',
read_permission => '.*',
write_permission => '.*',
- provider => 'rabbitmqctl',
- require => [
- Rabbitmq_user['wbadm'],
- Rabbitmq_vhost['buildd']
- ]
}
rabbitmq_user_permissions { 'mailadm@dsa':
configure_permission => '.*',
read_permission => '.*',
write_permission => '.*',
- provider => 'rabbitmqctl',
- require => [
- Rabbitmq_user['mailadm'],
- Rabbitmq_vhost['dsa']
- ]
}
rabbitmq_user_permissions { 'pet-devel@pet':
configure_permission => '.*',
read_permission => '.*',
write_permission => '.*',
- provider => 'rabbitmqctl',
- require => [
- Rabbitmq_user['pet-devel'],
- Rabbitmq_vhost['pet']
- ]
}
- rabbitmq_policy { 'mirror-dsa':
- vhost => 'dsa',
- match => '.*',
- policy => '{"ha-mode":"all"}',
- require => Rabbitmq_vhost['dsa']
+ rabbitmq_policy { 'mirror-dsa@dsa':
+ pattern => '.*',
+ priority => 0,
+ applyto => 'all',
+ definition => {
+ 'ha-mode' => 'all',
+ 'ha-sync-mode' => 'automatic',
+ },
}
- rabbitmq_policy { 'mirror-buildd':
- vhost => 'buildd',
- match => '.*',
- policy => '{"ha-mode":"all"}',
- require => Rabbitmq_vhost['buildd']
+ rabbitmq_policy { 'mirror-buildd@buildd':
+ pattern => '.*',
+ priority => 0,
+ applyto => 'all',
+ definition => {
+ 'ha-mode' => 'all',
+ 'ha-sync-mode' => 'automatic',
+ },
}
- rabbitmq_policy { 'mirror-packages':
- vhost => 'packages',
- match => '.*',
- policy => '{"ha-mode":"all"}',
- require => Rabbitmq_vhost['packages']
+ rabbitmq_policy { 'mirror-packages@packages':
+ pattern => '.*',
+ priority => 0,
+ applyto => 'all',
+ definition => {
+ 'ha-mode' => 'all',
+ 'ha-sync-mode' => 'automatic',
+ },
}
- rabbitmq_policy { 'mirror_pet':
- vhost => 'pet',
- match => '.*',
- policy => '{"ha-mode":"all"}',
- require => Rabbitmq_vhost['pet']
+ rabbitmq_policy { 'mirror_pet@pet':
+ pattern => '.*',
+ priority => 0,
+ applyto => 'all',
+ definition => {
+ 'ha-mode' => 'all',
+ 'ha-sync-mode' => 'automatic',
+ },
}
rabbitmq_plugin { 'rabbitmq_management':
ensure => present,
- provider => 'rabbitmqplugins',
- require => Package['rabbitmq-server'],
- notify => Service['rabbitmq-server']
}
rabbitmq_plugin { 'rabbitmq_management_agent':
ensure => present,
- provider => 'rabbitmqplugins',
- require => Package['rabbitmq-server'],
- notify => Service['rabbitmq-server']
}
rabbitmq_plugin { 'rabbitmq_tracing':
ensure => present,
- provider => 'rabbitmqplugins',
- require => Package['rabbitmq-server'],
- notify => Service['rabbitmq-server']
}
rabbitmq_plugin { 'rabbitmq_management_visualiser':
ensure => present,
- provider => 'rabbitmqplugins',
- require => Package['rabbitmq-server'],
- notify => Service['rabbitmq-server']
}
}