├── .editorconfig
├── .fixtures.yml
├── .gitattributes
├── .github
├── CONTRIBUTING.md
├── ISSUE_TEMPLATE.md
├── PULL_REQUEST_TEMPLATE.md
├── labeler.yml
├── release.yml
└── workflows
│ ├── ci.yml
│ ├── labeler.yml
│ ├── prepare_release.yml
│ └── release.yml
├── .gitignore
├── .msync.yml
├── .overcommit.yml
├── .pmtignore
├── .project
├── .puppet-lint.rc
├── .rubocop.yml
├── .rubocop_todo.yml
├── .sync.yml
├── CHANGELOG.md
├── Gemfile
├── HISTORY.md
├── LICENSE
├── MAINTAINERS.md
├── NOTICE
├── README.md
├── REFERENCE.md
├── Rakefile
├── data
├── common.yaml
├── family
│ ├── Archlinux.yaml
│ ├── Debian.yaml
│ ├── FreeBSD.yaml
│ ├── OpenBSD.yaml
│ ├── RedHat.yaml
│ └── Suse.yaml
└── os
│ └── CentOS.yaml
├── examples
├── cluster
│ └── join_cluster_and_change_name.pp
├── erlang_deps.pp
├── full.pp
├── permissions
│ └── add.pp
├── plugin.pp
├── repo
│ └── apt.pp
├── site.pp
├── user
│ └── add.pp
└── vhosts
│ └── add.pp
├── files
├── README.markdown
└── plugins
│ ├── amqp_client-2.3.1.ez
│ └── rabbit_stomp-2.3.1.ez
├── hiera.yaml
├── lib
├── facter
│ ├── erl_ssl_path.rb
│ ├── rabbitmq_clustername.rb
│ ├── rabbitmq_nodename.rb
│ ├── rabbitmq_plugins_dirs.rb
│ └── rabbitmq_version.rb
└── puppet
│ ├── provider
│ ├── rabbitmq_binding
│ │ └── rabbitmqadmin.rb
│ ├── rabbitmq_cli.rb
│ ├── rabbitmq_cluster
│ │ └── rabbitmqctl.rb
│ ├── rabbitmq_erlang_cookie
│ │ └── ruby.rb
│ ├── rabbitmq_exchange
│ │ └── rabbitmqadmin.rb
│ ├── rabbitmq_parameter
│ │ └── rabbitmqctl.rb
│ ├── rabbitmq_plugin
│ │ └── rabbitmqplugins.rb
│ ├── rabbitmq_policy
│ │ └── rabbitmqctl.rb
│ ├── rabbitmq_queue
│ │ └── rabbitmqadmin.rb
│ ├── rabbitmq_user
│ │ └── rabbitmqctl.rb
│ ├── rabbitmq_user_permissions
│ │ └── rabbitmqctl.rb
│ └── rabbitmq_vhost
│ │ └── rabbitmqctl.rb
│ └── type
│ ├── rabbitmq_binding.rb
│ ├── rabbitmq_cluster.rb
│ ├── rabbitmq_erlang_cookie.rb
│ ├── rabbitmq_exchange.rb
│ ├── rabbitmq_parameter.rb
│ ├── rabbitmq_plugin.rb
│ ├── rabbitmq_policy.rb
│ ├── rabbitmq_queue.rb
│ ├── rabbitmq_user.rb
│ ├── rabbitmq_user_permissions.rb
│ └── rabbitmq_vhost.rb
├── locales
└── config.yaml
├── manifests
├── config.pp
├── init.pp
├── install.pp
├── install
│ └── rabbitmqadmin.pp
├── management.pp
├── repo
│ ├── apt.pp
│ └── rhel.pp
└── service.pp
├── metadata.json
├── spec
├── README.markdown
├── acceptance
│ ├── class_spec.rb
│ ├── clustering_spec.rb
│ ├── delete_guest_user_spec.rb
│ ├── parameter_spec.rb
│ ├── policy_spec.rb
│ ├── queue_spec.rb
│ ├── rabbitmqadmin_spec.rb
│ ├── user_spec.rb
│ └── vhost_spec.rb
├── classes
│ └── rabbitmq_spec.rb
├── spec_helper.rb
├── spec_helper_acceptance.rb
├── spec_helper_local.rb
└── unit
│ ├── facter
│ └── util
│ │ ├── fact_erl_ssl_path_spec.rb
│ │ ├── fact_rabbitmq_clustername_spec.rb
│ │ ├── fact_rabbitmq_nodename_spec.rb
│ │ ├── fact_rabbitmq_plugins_dirs_spec.rb
│ │ └── fact_rabbitmq_version_spec.rb
│ └── puppet
│ ├── provider
│ ├── rabbitmq_binding
│ │ └── rabbitmqadmin_spec.rb
│ ├── rabbitmq_cli_spec.rb
│ ├── rabbitmq_cluster
│ │ └── rabbitmqctl_spec.rb
│ ├── rabbitmq_exchange
│ │ └── rabbitmqadmin_spec.rb
│ ├── rabbitmq_parameter
│ │ ├── rabbitmqctl_federation_spec.rb
│ │ └── rabbitmqctl_spec.rb
│ ├── rabbitmq_plugin
│ │ └── rabbitmqctl_spec.rb
│ ├── rabbitmq_policy
│ │ └── rabbitmqctl_spec.rb
│ ├── rabbitmq_queue
│ │ └── rabbitmqadmin_spec.rb
│ ├── rabbitmq_user
│ │ └── rabbitmqctl_spec.rb
│ ├── rabbitmq_user_permissions
│ │ └── rabbitmqctl_spec.rb
│ └── rabbitmq_vhost
│ │ └── rabbitmqctl_spec.rb
│ └── type
│ ├── rabbitmq_binding_spec.rb
│ ├── rabbitmq_cluster_spec.rb
│ ├── rabbitmq_exchange_spec.rb
│ ├── rabbitmq_parameter_spec.rb
│ ├── rabbitmq_plugin_spec.rb
│ ├── rabbitmq_policy_spec.rb
│ ├── rabbitmq_queue_spec.rb
│ ├── rabbitmq_user_permissions_spec.rb
│ ├── rabbitmq_user_spec.rb
│ └── rabbitmq_vhost_spec.rb
└── templates
├── README.markdown
├── enabled_plugins.epp
├── inetrc.erb
├── limits.conf
├── rabbitmq-env.conf.epp
├── rabbitmq.config.epp
└── rabbitmqadmin.conf.epp
/.editorconfig:
--------------------------------------------------------------------------------
1 | # editorconfig.org
2 |
3 | # Managed by modulesync - DO NOT EDIT
4 | # https://voxpupuli.org/docs/updating-files-managed-with-modulesync/
5 |
6 | root = true
7 |
8 | [*]
9 | charset = utf-8
10 | end_of_line = lf
11 | indent_size = 2
12 | tab_width = 2
13 | indent_style = space
14 | insert_final_newline = true
15 | trim_trailing_whitespace = true
16 |
--------------------------------------------------------------------------------
/.fixtures.yml:
--------------------------------------------------------------------------------
1 | ---
2 | fixtures:
3 | repositories:
4 | stdlib: 'https://github.com/puppetlabs/puppetlabs-stdlib'
5 | apt: 'https://github.com/puppetlabs/puppetlabs-apt'
6 | archive: 'https://github.com/voxpupuli/puppet-archive'
7 | systemd: 'https://github.com/voxpupuli/puppet-systemd'
8 | yumrepo_core: 'https://github.com/puppetlabs/puppetlabs-yumrepo_core'
9 |
--------------------------------------------------------------------------------
/.gitattributes:
--------------------------------------------------------------------------------
1 | #This file is generated by ModuleSync, do not edit.
2 | *.rb eol=lf
3 | *.erb eol=lf
4 | *.pp eol=lf
5 | *.sh eol=lf
6 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE.md:
--------------------------------------------------------------------------------
1 |
10 |
11 | ## Affected Puppet, Ruby, OS and module versions/distributions
12 |
13 | - Puppet:
14 | - Ruby:
15 | - Distribution:
16 | - Module version:
17 |
18 | ## How to reproduce (e.g Puppet code you use)
19 |
20 | ## What are you seeing
21 |
22 | ## What behaviour did you expect instead
23 |
24 | ## Output log
25 |
26 | ## Any additional information you'd like to impart
27 |
--------------------------------------------------------------------------------
/.github/PULL_REQUEST_TEMPLATE.md:
--------------------------------------------------------------------------------
1 |
9 | #### Pull Request (PR) description
10 |
13 |
14 | #### This Pull Request (PR) fixes the following issues
15 |
21 |
--------------------------------------------------------------------------------
/.github/labeler.yml:
--------------------------------------------------------------------------------
1 | ---
2 | # Managed by modulesync - DO NOT EDIT
3 | # https://voxpupuli.org/docs/updating-files-managed-with-modulesync/
4 |
5 | skip-changelog:
6 | - head-branch: ['^release-*', 'release']
7 |
--------------------------------------------------------------------------------
/.github/release.yml:
--------------------------------------------------------------------------------
1 | ---
2 | # Managed by modulesync - DO NOT EDIT
3 | # https://voxpupuli.org/docs/updating-files-managed-with-modulesync/
4 |
5 | # https://docs.github.com/en/repositories/releasing-projects-on-github/automatically-generated-release-notes
6 |
7 | changelog:
8 | exclude:
9 | labels:
10 | - duplicate
11 | - invalid
12 | - modulesync
13 | - question
14 | - skip-changelog
15 | - wont-fix
16 | - wontfix
17 |
18 | categories:
19 | - title: Breaking Changes 🛠
20 | labels:
21 | - backwards-incompatible
22 |
23 | - title: New Features 🎉
24 | labels:
25 | - enhancement
26 |
27 | - title: Bug Fixes 🐛
28 | labels:
29 | - bug
30 |
31 | - title: Documentation Updates 📚
32 | labels:
33 | - documentation
34 | - docs
35 |
36 | - title: Dependency Updates ⬆️
37 | labels:
38 | - dependencies
39 |
40 | - title: Other Changes
41 | labels:
42 | - "*"
43 |
--------------------------------------------------------------------------------
/.github/workflows/ci.yml:
--------------------------------------------------------------------------------
1 | ---
2 | # Managed by modulesync - DO NOT EDIT
3 | # https://voxpupuli.org/docs/updating-files-managed-with-modulesync/
4 |
5 | name: CI
6 |
7 | # yamllint disable-line rule:truthy
8 | on:
9 | pull_request: {}
10 | push:
11 | branches:
12 | - main
13 | - master
14 |
15 | concurrency:
16 | group: ${{ github.ref_name }}
17 | cancel-in-progress: true
18 |
19 | jobs:
20 | puppet:
21 | name: Puppet
22 | uses: voxpupuli/gha-puppet/.github/workflows/beaker.yml@v3
23 |
--------------------------------------------------------------------------------
/.github/workflows/labeler.yml:
--------------------------------------------------------------------------------
1 | ---
2 | # Managed by modulesync - DO NOT EDIT
3 | # https://voxpupuli.org/docs/updating-files-managed-with-modulesync/
4 |
5 | name: "Pull Request Labeler"
6 |
7 | # yamllint disable-line rule:truthy
8 | on:
9 | pull_request_target: {}
10 |
11 | jobs:
12 | labeler:
13 | permissions:
14 | contents: read
15 | pull-requests: write
16 | runs-on: ubuntu-latest
17 | steps:
18 | - uses: actions/labeler@v5
19 |
--------------------------------------------------------------------------------
/.github/workflows/prepare_release.yml:
--------------------------------------------------------------------------------
1 | ---
2 | # Managed by modulesync - DO NOT EDIT
3 | # https://voxpupuli.org/docs/updating-files-managed-with-modulesync/
4 |
5 | name: 'Prepare Release'
6 |
7 | on:
8 | workflow_dispatch:
9 | inputs:
10 | version:
11 | description: 'Module version to be released. Must be a valid semver string without leading v. (1.2.3)'
12 | required: false
13 |
14 | jobs:
15 | release_prep:
16 | uses: 'voxpupuli/gha-puppet/.github/workflows/prepare_release.yml@v3'
17 | with:
18 | version: ${{ github.event.inputs.version }}
19 | allowed_owner: 'voxpupuli'
20 | secrets:
21 | # Configure secrets here:
22 | # https://docs.github.com/en/actions/security-guides/encrypted-secrets
23 | github_pat: '${{ secrets.PCCI_PAT_RELEASE_PREP }}'
24 |
--------------------------------------------------------------------------------
/.github/workflows/release.yml:
--------------------------------------------------------------------------------
1 | ---
2 | # Managed by modulesync - DO NOT EDIT
3 | # https://voxpupuli.org/docs/updating-files-managed-with-modulesync/
4 |
5 | name: Release
6 |
7 | # yamllint disable-line rule:truthy
8 | on:
9 | push:
10 | tags:
11 | - '*'
12 |
13 | jobs:
14 | release:
15 | name: Release
16 | uses: voxpupuli/gha-puppet/.github/workflows/release.yml@v3
17 | with:
18 | allowed_owner: 'voxpupuli'
19 | secrets:
20 | # Configure secrets here:
21 | # https://docs.github.com/en/actions/security-guides/encrypted-secrets
22 | username: ${{ secrets.PUPPET_FORGE_USERNAME }}
23 | api_key: ${{ secrets.PUPPET_FORGE_API_KEY }}
24 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Managed by modulesync - DO NOT EDIT
2 | # https://voxpupuli.org/docs/updating-files-managed-with-modulesync/
3 |
4 | /pkg/
5 | /Gemfile.lock
6 | /Gemfile.local
7 | /vendor/
8 | /.vendor/
9 | /spec/fixtures/manifests/
10 | /spec/fixtures/modules/
11 | /.vagrant/
12 | /.bundle/
13 | /.ruby-version
14 | /coverage/
15 | /log/
16 | /.idea/
17 | /.dependencies/
18 | /.librarian/
19 | /Puppetfile.lock
20 | *.iml
21 | .*.sw?
22 | /.yardoc/
23 | /Guardfile
24 | bolt-debug.log
25 | .rerun.json
26 |
--------------------------------------------------------------------------------
/.msync.yml:
--------------------------------------------------------------------------------
1 | ---
2 | # Managed by modulesync - DO NOT EDIT
3 | # https://voxpupuli.org/docs/updating-files-managed-with-modulesync/
4 |
5 | modulesync_config_version: '9.5.0'
6 |
--------------------------------------------------------------------------------
/.overcommit.yml:
--------------------------------------------------------------------------------
1 | # Managed by modulesync - DO NOT EDIT
2 | # https://voxpupuli.org/docs/updating-files-managed-with-modulesync/
3 | #
4 | # Hooks are only enabled if you take action.
5 | #
6 | # To enable the hooks run:
7 | #
8 | # ```
9 | # bundle exec overcommit --install
10 | # # ensure .overcommit.yml does not harm to you and then
11 | # bundle exec overcommit --sign
12 | # ```
13 | #
14 | # (it will manage the .git/hooks directory):
15 | #
16 | # Examples howto skip a test for a commit or push:
17 | #
18 | # ```
19 | # SKIP=RuboCop git commit
20 | # SKIP=PuppetLint git commit
21 | # SKIP=RakeTask git push
22 | # ```
23 | #
24 | # Don't invoke overcommit at all:
25 | #
26 | # ```
27 | # OVERCOMMIT_DISABLE=1 git commit
28 | # ```
29 | #
30 | # Read more about overcommit: https://github.com/brigade/overcommit
31 | #
32 | # To manage this config yourself in your module add
33 | #
34 | # ```
35 | # .overcommit.yml:
36 | # unmanaged: true
37 | # ```
38 | #
39 | # to your modules .sync.yml config
40 | ---
41 | PreCommit:
42 | RuboCop:
43 | enabled: true
44 | description: 'Runs rubocop on modified files only'
45 | command: ['bundle', 'exec', 'rubocop']
46 | RakeTarget:
47 | enabled: true
48 | description: 'Runs lint on modified files only'
49 | targets:
50 | - 'lint'
51 | command: ['bundle', 'exec', 'rake']
52 | YamlSyntax:
53 | enabled: true
54 | JsonSyntax:
55 | enabled: true
56 | TrailingWhitespace:
57 | enabled: true
58 |
59 | PrePush:
60 | RakeTarget:
61 | enabled: true
62 | description: 'Run rake targets'
63 | targets:
64 | - 'validate'
65 | - 'test'
66 | - 'rubocop'
67 | command: ['bundle', 'exec', 'rake']
68 |
--------------------------------------------------------------------------------
/.pmtignore:
--------------------------------------------------------------------------------
1 | # Managed by modulesync - DO NOT EDIT
2 | # https://voxpupuli.org/docs/updating-files-managed-with-modulesync/
3 |
4 | /docs/
5 | /pkg/
6 | /Gemfile
7 | /Gemfile.lock
8 | /Gemfile.local
9 | /vendor/
10 | /.vendor/
11 | /spec/
12 | /Rakefile
13 | /.vagrant/
14 | /.bundle/
15 | /.ruby-version
16 | /coverage/
17 | /log/
18 | /.idea/
19 | /.dependencies/
20 | /.github/
21 | /.librarian/
22 | /Puppetfile.lock
23 | /Puppetfile
24 | *.iml
25 | /.editorconfig
26 | /.fixtures.yml
27 | /.gitignore
28 | /.msync.yml
29 | /.overcommit.yml
30 | /.pmtignore
31 | /.rspec
32 | /.rspec_parallel
33 | /.rubocop.yml
34 | /.sync.yml
35 | .*.sw?
36 | /.yardoc/
37 | /.yardopts
38 | /Dockerfile
39 | /HISTORY.md
40 |
--------------------------------------------------------------------------------
/.project:
--------------------------------------------------------------------------------
1 |
2 |
3 | puppetlabs-rabbitmq
4 |
5 |
6 |
7 |
8 |
9 | com.puppetlabs.geppetto.pp.dsl.ui.modulefileBuilder
10 |
11 |
12 |
13 |
14 | org.eclipse.xtext.ui.shared.xtextBuilder
15 |
16 |
17 |
18 |
19 |
20 | com.puppetlabs.geppetto.pp.dsl.ui.puppetNature
21 | org.eclipse.xtext.ui.shared.xtextNature
22 |
23 |
24 |
--------------------------------------------------------------------------------
/.puppet-lint.rc:
--------------------------------------------------------------------------------
1 | # Managed by modulesync - DO NOT EDIT
2 | # https://voxpupuli.org/docs/updating-files-managed-with-modulesync/
3 |
4 | --fail-on-warnings
5 |
--------------------------------------------------------------------------------
/.rubocop.yml:
--------------------------------------------------------------------------------
1 | ---
2 | # Managed by modulesync - DO NOT EDIT
3 | # https://voxpupuli.org/docs/updating-files-managed-with-modulesync/
4 |
5 | inherit_from: .rubocop_todo.yml
6 | inherit_gem:
7 | voxpupuli-test: rubocop.yml
8 |
--------------------------------------------------------------------------------
/.rubocop_todo.yml:
--------------------------------------------------------------------------------
1 | # This configuration was generated by
2 | # `rubocop --auto-gen-config`
3 | # on 2024-05-18 22:27:55 UTC using RuboCop version 1.50.2.
4 | # The point is for the user to remove these configuration records
5 | # one by one as the offenses are removed from the code base.
6 | # Note that changes in the inspected code, or installation of new
7 | # versions of RuboCop, may require this file to be generated again.
8 |
9 | # Offense count: 8
10 | # This cop supports unsafe autocorrection (--autocorrect-all).
11 | RSpec/BeEq:
12 | Exclude:
13 | - 'spec/unit/puppet/provider/rabbitmq_plugin/rabbitmqctl_spec.rb'
14 | - 'spec/unit/puppet/provider/rabbitmq_policy/rabbitmqctl_spec.rb'
15 | - 'spec/unit/puppet/provider/rabbitmq_user_permissions/rabbitmqctl_spec.rb'
16 | - 'spec/unit/puppet/provider/rabbitmq_vhost/rabbitmqctl_spec.rb'
17 | - 'spec/unit/puppet/type/rabbitmq_user_permissions_spec.rb'
18 |
19 | # Offense count: 3
20 | RSpec/PendingWithoutReason:
21 | Exclude:
22 | - 'spec/acceptance/class_spec.rb'
23 |
24 | # Offense count: 4
25 | RSpec/RepeatedExampleGroupBody:
26 | Exclude:
27 | - 'spec/classes/rabbitmq_spec.rb'
28 |
29 | # Offense count: 14
30 | RSpec/RepeatedExampleGroupDescription:
31 | Exclude:
32 | - 'spec/classes/rabbitmq_spec.rb'
33 |
--------------------------------------------------------------------------------
/.sync.yml:
--------------------------------------------------------------------------------
1 | ---
2 | spec/spec_helper.rb:
3 | facterdb_string_keys: true
4 | mock_with: ':mocha'
5 | spec_overrides: "require 'spec_helper_local'"
6 | .puppet-lint.rc:
7 | enabled_lint_checks:
8 | - parameter_documentation
9 | - parameter_types
10 |
--------------------------------------------------------------------------------
/Gemfile:
--------------------------------------------------------------------------------
1 | # Managed by modulesync - DO NOT EDIT
2 | # https://voxpupuli.org/docs/updating-files-managed-with-modulesync/
3 |
4 | source ENV['GEM_SOURCE'] || 'https://rubygems.org'
5 |
6 | group :test do
7 | gem 'voxpupuli-test', '~> 9.0', :require => false
8 | gem 'coveralls', :require => false
9 | gem 'simplecov-console', :require => false
10 | gem 'puppet_metadata', '~> 5.0', :require => false
11 | end
12 |
13 | group :development do
14 | gem 'guard-rake', :require => false
15 | gem 'overcommit', '>= 0.39.1', :require => false
16 | end
17 |
18 | group :system_tests do
19 | gem 'voxpupuli-acceptance', '~> 3.5', :require => false
20 | end
21 |
22 | group :release do
23 | gem 'voxpupuli-release', '~> 3.0', :require => false
24 | end
25 |
26 | gem 'rake', :require => false
27 | gem 'facter', ENV['FACTER_GEM_VERSION'], :require => false, :groups => [:test]
28 |
29 | puppetversion = ENV['PUPPET_GEM_VERSION'] || [">= 7.24", "< 9"]
30 | gem 'puppet', puppetversion, :require => false, :groups => [:test]
31 |
32 | # vim: syntax=ruby
33 |
--------------------------------------------------------------------------------
/MAINTAINERS.md:
--------------------------------------------------------------------------------
1 | ## Maintenance
2 |
3 | Maintainers:
4 | - Puppet Forge Modules Team `forge-modules |at| puppet |dot| com`
5 |
6 | Tickets: https://tickets.puppet.com/browse/MODULES. Make sure to set component to `rabbitmq`.
7 |
--------------------------------------------------------------------------------
/NOTICE:
--------------------------------------------------------------------------------
1 | Puppet Module - puppetlabs-rabbitmq
2 |
3 | Copyright 2017 Puppet, Inc.
4 |
5 | Licensed under the Apache License, Version 2.0 (the "License");
6 | you may not use this file except in compliance with the License.
7 | You may obtain a copy of the License at
8 |
9 | http://www.apache.org/licenses/LICENSE-2.0
10 |
11 | Unless required by applicable law or agreed to in writing, software
12 | distributed under the License is distributed on an "AS IS" BASIS,
13 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | See the License for the specific language governing permissions and
15 | limitations under the License.
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # rabbitmq
2 |
3 | [](https://github.com/voxpupuli/puppet-rabbitmq/blob/master/LICENSE)
4 | [](https://github.com/voxpupuli/puppet-rabbitmq/actions)
5 | [](https://forge.puppetlabs.com/puppet/rabbitmq)
6 | [](https://forge.puppetlabs.com/puppet/rabbitmq)
7 | [](https://forge.puppetlabs.com/puppet/rabbitmq)
8 | [](https://forge.puppetlabs.com/puppet/rabbitmq)
9 |
10 | #### Table of Contents
11 |
12 | 1. [Overview](#overview)
13 | 2. [Module Description - What the module does and why it is useful](#module-description)
14 | 3. [Setup - The basics of getting started with rabbitmq](#setup)
15 | * [What rabbitmq affects](#what-rabbitmq-affects)
16 | * [Setup requirements](#setup-requirements)
17 | 4. [Usage - Configuration options and additional functionality](#usage)
18 | 5. [Reference - An under-the-hood peek at what the module is doing and how](#reference)
19 | 5. [Limitations - OS compatibility, etc.](#limitations)
20 | * [RedHat module dependencies](#redhat-module-dependecies)
21 | 6. [Development - Guide for contributing to the module](#development)
22 |
23 | ## Overview
24 |
25 | This module manages RabbitMQ (www.rabbitmq.com)
26 |
27 | ## Module Description
28 | The rabbitmq module sets up rabbitmq and has a number of providers to manage
29 | everything from vhosts to exchanges after setup.
30 |
31 | This module has been tested against 3.5.x and 3.6.x (as well as earlier
32 | versions) and is known to not support all features against versions
33 | prior to 2.7.1.
34 |
35 | ## Setup
36 |
37 | ### What rabbitmq affects
38 |
39 | * rabbitmq repository files.
40 | * rabbitmq package.
41 | * rabbitmq configuration file.
42 | * rabbitmq service.
43 |
44 | ## Usage
45 |
46 | All options and configuration can be done through interacting with the parameters
47 | on the main rabbitmq class.
48 | These are now documented via [Puppet Strings](https://github.com/puppetlabs/puppet-strings)
49 |
50 | You can view example usage in [REFERENCE](REFERENCE.md).
51 |
52 | **[puppet/epel](https://forge.puppet.com/modules/puppet/epel) is a soft dependency. If you're on CentOS 7 and don't want to require it, set `$require_epel` to `false`**
53 |
54 | Version v13.2.0 and older also added an erlang repository on CentOS 7. That isn't used and can be safely removed.
55 |
56 | ## Reference
57 |
58 | See [REFERENCE](REFERENCE.md).
59 |
60 | ## Development
61 |
62 | This module is maintained by [Vox Pupuli](https://voxpupuli.org/). Voxpupuli
63 | welcomes new contributions to this module, especially those that include
64 | documentation and rspec tests. We are happy to provide guidance if necessary.
65 |
66 | Please see [CONTRIBUTING](.github/CONTRIBUTING.md) for more details.
67 |
68 | ### Authors
69 | * Jeff McCune
70 | * Dan Bode
71 | * RPM/RHEL packages by Vincent Janelle
72 | * Puppetlabs Module Team
73 | * Voxpupuli Team
74 |
--------------------------------------------------------------------------------
/Rakefile:
--------------------------------------------------------------------------------
1 | # Managed by modulesync - DO NOT EDIT
2 | # https://voxpupuli.org/docs/updating-files-managed-with-modulesync/
3 |
4 | # Attempt to load voxpupuli-test (which pulls in puppetlabs_spec_helper),
5 | # otherwise attempt to load it directly.
6 | begin
7 | require 'voxpupuli/test/rake'
8 | rescue LoadError
9 | begin
10 | require 'puppetlabs_spec_helper/rake_tasks'
11 | rescue LoadError
12 | end
13 | end
14 |
15 | # load optional tasks for acceptance
16 | # only available if gem group releases is installed
17 | begin
18 | require 'voxpupuli/acceptance/rake'
19 | rescue LoadError
20 | end
21 |
22 | # load optional tasks for releases
23 | # only available if gem group releases is installed
24 | begin
25 | require 'voxpupuli/release/rake_tasks'
26 | rescue LoadError
27 | # voxpupuli-release not present
28 | else
29 | GCGConfig.user = 'voxpupuli'
30 | GCGConfig.project = 'puppet-rabbitmq'
31 | end
32 |
33 | desc "Run main 'test' task and report merged results to coveralls"
34 | task test_with_coveralls: [:test] do
35 | if Dir.exist?(File.expand_path('../lib', __FILE__))
36 | require 'coveralls/rake/task'
37 | Coveralls::RakeTask.new
38 | Rake::Task['coveralls:push'].invoke
39 | else
40 | puts 'Skipping reporting to coveralls. Module has no lib dir'
41 | end
42 | end
43 |
44 | # vim: syntax=ruby
45 |
--------------------------------------------------------------------------------
/data/common.yaml:
--------------------------------------------------------------------------------
1 | ---
2 | rabbitmq::admin_enable: true
3 | rabbitmq::management_enable: false
4 | rabbitmq::use_config_file_for_plugins: false
5 | rabbitmq::cluster: {}
6 | rabbitmq::cluster_node_type: 'disc'
7 | rabbitmq::cluster_nodes: []
8 | rabbitmq::config: 'rabbitmq/rabbitmq.config.epp'
9 | rabbitmq::config_cluster: false
10 | rabbitmq::config_path: '/etc/rabbitmq/rabbitmq.config'
11 | rabbitmq::config_ranch: true
12 | rabbitmq::config_stomp: false
13 | rabbitmq::config_shovel: false
14 | rabbitmq::config_shovel_statics: {}
15 | rabbitmq::default_user: 'guest'
16 | rabbitmq::default_pass: 'guest'
17 | rabbitmq::delete_guest_user: false
18 | rabbitmq::env_config: 'rabbitmq/rabbitmq-env.conf.epp'
19 | rabbitmq::env_config_path: '/etc/rabbitmq/rabbitmq-env.conf'
20 | rabbitmq::erlang_cookie: ~
21 | rabbitmq::interface: ~
22 | rabbitmq::management_ip_address: ~
23 | rabbitmq::management_port: 15672
24 | rabbitmq::management_ssl: true
25 | rabbitmq::management_hostname: ~
26 | rabbitmq::node_ip_address: ~
27 | rabbitmq::package_apt_pin: ~
28 | rabbitmq::package_ensure: 'installed'
29 | rabbitmq::package_gpg_key: ~
30 | rabbitmq::repo_gpg_key: ~
31 | rabbitmq::package_name: 'rabbitmq'
32 | rabbitmq::package_source: ~
33 | rabbitmq::package_provider: ~
34 | rabbitmq::repos_ensure: false
35 | rabbitmq::manage_python: true
36 | rabbitmq::python_package: 'python'
37 | rabbitmq::rabbitmq_user: 'rabbitmq'
38 | rabbitmq::rabbitmq_group: 'rabbitmq'
39 | rabbitmq::rabbitmq_home: '/var/lib/rabbitmq'
40 | rabbitmq::port: 5672
41 | rabbitmq::tcp_keepalive: false
42 | rabbitmq::tcp_backlog: 128
43 | rabbitmq::tcp_sndbuf: ~
44 | rabbitmq::tcp_recbuf: ~
45 | rabbitmq::heartbeat: ~
46 | rabbitmq::service_ensure: 'running'
47 | rabbitmq::service_manage: true
48 | rabbitmq::service_name: 'rabbitmq'
49 | rabbitmq::ssl: false
50 | rabbitmq::ssl_only: false
51 | rabbitmq::ssl_cacert: ~
52 | rabbitmq::ssl_cert: ~
53 | rabbitmq::ssl_key: ~
54 | rabbitmq::ssl_depth: ~
55 | rabbitmq::ssl_cert_password: ~
56 | rabbitmq::ssl_port: 5671
57 | rabbitmq::ssl_interface: ~
58 | rabbitmq::ssl_management_port: 15671
59 | rabbitmq::ssl_stomp_port: 6164
60 | rabbitmq::ssl_verify: 'verify_none'
61 | rabbitmq::ssl_fail_if_no_peer_cert: false
62 | rabbitmq::ssl_management_verify: 'verify_none'
63 | rabbitmq::ssl_management_fail_if_no_peer_cert: false
64 | rabbitmq::ssl_versions: ~
65 | rabbitmq::ssl_secure_renegotiate: true
66 | rabbitmq::ssl_reuse_sessions: true
67 | rabbitmq::ssl_honor_cipher_order: true
68 | rabbitmq::ssl_dhfile: ~
69 | rabbitmq::ssl_ciphers: []
70 | rabbitmq::stomp_ensure: false
71 | rabbitmq::ldap_auth: false
72 | rabbitmq::ldap_server: 'ldap'
73 | rabbitmq::ldap_user_dn_pattern: ~
74 | rabbitmq::ldap_other_bind: 'anon'
75 | rabbitmq::ldap_use_ssl: false
76 | rabbitmq::ldap_port: 389
77 | rabbitmq::ldap_log: false
78 | rabbitmq::ldap_config_variables: {}
79 | rabbitmq::stomp_port: 6163
80 | rabbitmq::stomp_ssl_only: false
81 | rabbitmq::wipe_db_on_cookie_change: false
82 | rabbitmq::cluster_partition_handling: 'ignore'
83 | rabbitmq::file_limit: 16384
84 | rabbitmq::environment_variables:
85 | 'LC_ALL': 'en_US.UTF-8'
86 | rabbitmq::config_variables: {}
87 | rabbitmq::config_kernel_variables: {}
88 | rabbitmq::config_management_variables: {}
89 | rabbitmq::config_additional_variables: {}
90 | rabbitmq::auth_backends: ~
91 | rabbitmq::key_content: ~
92 | rabbitmq::collect_statistics_interval: ~
93 | rabbitmq::ipv6: false
94 | rabbitmq::inetrc_config: 'rabbitmq/inetrc.erb'
95 | rabbitmq::inetrc_config_path: '/etc/rabbitmq/inetrc'
96 | rabbitmq::ssl_erl_dist: false
97 | rabbitmq::rabbitmqadmin_package: ~
98 | rabbitmq::archive_options: []
99 | rabbitmq::loopback_users:
100 | - 'guest'
101 | rabbitmq::service_restart: true
102 |
--------------------------------------------------------------------------------
/data/family/Archlinux.yaml:
--------------------------------------------------------------------------------
1 | ---
2 | rabbitmq::python_package: 'python'
3 |
--------------------------------------------------------------------------------
/data/family/Debian.yaml:
--------------------------------------------------------------------------------
1 | ---
2 | rabbitmq::python_package: 'python3'
3 | rabbitmq::package_name: 'rabbitmq-server'
4 | rabbitmq::service_name: 'rabbitmq-server'
5 | rabbitmq::package_gpg_key: 'https://packagecloud.io/rabbitmq/rabbitmq-server/gpgkey'
6 |
--------------------------------------------------------------------------------
/data/family/FreeBSD.yaml:
--------------------------------------------------------------------------------
1 | ---
2 | rabbitmq::python_package: 'python38'
3 | rabbitmq::rabbitmq_home: '/var/db/rabbitmq'
4 | rabbitmq::config_path: '/usr/local/etc/rabbitmq/rabbitmq.config'
5 | rabbitmq::env_config_path: '/usr/local/etc/rabbitmq/rabbitmq-env.conf'
6 | rabbitmq::inetrc_config_path: '/usr/local/etc/rabbitmq/inetrc'
7 |
--------------------------------------------------------------------------------
/data/family/OpenBSD.yaml:
--------------------------------------------------------------------------------
1 | ---
2 | rabbitmq::python_package: 'python2'
3 | rabbitmq::rabbitmq_user: '_rabbitmq'
4 | rabbitmq::rabbitmq_group: '_rabbitmq'
5 | rabbitmq::rabbitmq_home: '/var/rabbitmq'
6 |
--------------------------------------------------------------------------------
/data/family/RedHat.yaml:
--------------------------------------------------------------------------------
1 | ---
2 | rabbitmq::package_name: 'rabbitmq-server'
3 | rabbitmq::service_name: 'rabbitmq-server'
4 | rabbitmq::package_gpg_key: 'https://github.com/rabbitmq/signing-keys/releases/download/2.0/rabbitmq-release-signing-key.asc'
5 | rabbitmq::repo_gpg_key: 'https://packagecloud.io/rabbitmq/rabbitmq-server/gpgkey'
--------------------------------------------------------------------------------
/data/family/Suse.yaml:
--------------------------------------------------------------------------------
1 | ---
2 | rabbitmq::package_name:
3 | - 'rabbitmq-server'
4 | - 'rabbitmq-server-plugins'
5 | rabbitmq::service_name: 'rabbitmq-server'
6 |
--------------------------------------------------------------------------------
/data/os/CentOS.yaml:
--------------------------------------------------------------------------------
1 | rabbitmq::enable_centos_release: true
2 |
--------------------------------------------------------------------------------
/examples/cluster/join_cluster_and_change_name.pp:
--------------------------------------------------------------------------------
1 | # This sets the cluster name to `test_cluster`
2 | # If run on another host than host1, this will join the host1's cluster
3 | rabbitmq_cluster { 'test_cluster':
4 | init_node => 'host1',
5 | }
6 |
--------------------------------------------------------------------------------
/examples/erlang_deps.pp:
--------------------------------------------------------------------------------
1 | # install first the garethr-erlang module. See README.md
2 | include erlang
3 |
4 | class { 'erlang': epel_enable => true }
5 | Class['erlang'] -> Class['rabbitmq']
6 |
--------------------------------------------------------------------------------
/examples/full.pp:
--------------------------------------------------------------------------------
1 | class { 'rabbitmq':
2 | delete_guest_user => true,
3 | repos_ensure => true,
4 | package_apt_pin => 900,
5 | }
6 |
7 | -> rabbitmq_user { 'dan':
8 | admin => true,
9 | password => 'pass',
10 | provider => 'rabbitmqctl',
11 | }
12 |
13 | -> rabbitmq_vhost { 'myhost':
14 | provider => 'rabbitmqctl',
15 | }
16 |
17 | rabbitmq_user_permissions { 'dan@myhost':
18 | configure_permission => '.*',
19 | read_permission => '.*',
20 | write_permission => '.*',
21 | provider => 'rabbitmqctl',
22 | }
23 |
--------------------------------------------------------------------------------
/examples/permissions/add.pp:
--------------------------------------------------------------------------------
1 | rabbitmq_user { 'blah7':
2 | password => 'foo',
3 | }
4 | rabbitmq_vhost { 'test5': }
5 | rabbitmq_user_permissions { 'blah7@test5':
6 | configure_permission => 'config2',
7 | read_permission => 'ready',
8 | #write_permission => 'ready',
9 | }
10 |
--------------------------------------------------------------------------------
/examples/plugin.pp:
--------------------------------------------------------------------------------
1 | $rabbitmq_plugins = ['amqp_client', 'rabbitmq_stomp']
2 |
3 | class { 'rabbitmq':
4 | config_stomp => true,
5 | }
6 |
7 | rabbitmq_plugin { $rabbitmq_plugins:
8 | ensure => present,
9 | require => Class['rabbitmq'],
10 | provider => 'rabbitmqplugins',
11 | }
12 |
--------------------------------------------------------------------------------
/examples/repo/apt.pp:
--------------------------------------------------------------------------------
1 | # requires pupetlabs-apt
2 | include rabbitmq::repo::apt
3 |
--------------------------------------------------------------------------------
/examples/site.pp:
--------------------------------------------------------------------------------
1 | node default {
2 | $rabbitmq_plugins = ['amqp_client', 'rabbitmq_stomp']
3 |
4 | class { 'rabbitmq':
5 | config => '[ {rabbit_stomp, [{tcp_listeners, [1234]} ]} ].',
6 | }
7 |
8 | # Required for MCollective
9 | rabbitmq_plugin { $rabbitmq_plugins:
10 | ensure => present,
11 | require => Class['rabbitmq'],
12 | provider => 'rabbitmqplugins',
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/examples/user/add.pp:
--------------------------------------------------------------------------------
1 | rabbitmq_user { ['blah2', 'blah3', 'blah4']:
2 | password => 'phoey!',
3 | #provider => 'rabbitmqctl',
4 | }
5 |
--------------------------------------------------------------------------------
/examples/vhosts/add.pp:
--------------------------------------------------------------------------------
1 | rabbitmq_vhost { ['fooey', 'blah']: }
2 |
--------------------------------------------------------------------------------
/files/README.markdown:
--------------------------------------------------------------------------------
1 | Files
2 | =====
3 |
4 | Puppet comes with both a client and server for copying files around. The file
5 | serving function is provided as part of the central Puppet daemon,
6 | puppetmasterd, and the client function is used through the source attribute of
7 | file objects. Learn more at
8 | http://projects.puppetlabs.com/projects/puppet/wiki/File_Serving_Configuration
9 |
10 | You can use managed files like this:
11 |
12 | class myclass {
13 | package { mypackage: ensure => latest }
14 | service { myservice: ensure => running }
15 | file { "/etc/myfile":
16 | source => "puppet://$servername/modules/mymodule/myfile"
17 | }
18 | }
19 |
20 | The files are searched for in:
21 |
22 | $modulepath/mymodule/files/myfile
23 |
--------------------------------------------------------------------------------
/files/plugins/amqp_client-2.3.1.ez:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/voxpupuli/puppet-rabbitmq/ae4ffea04b66fb624b2fd7775c56144adf0f0d60/files/plugins/amqp_client-2.3.1.ez
--------------------------------------------------------------------------------
/files/plugins/rabbit_stomp-2.3.1.ez:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/voxpupuli/puppet-rabbitmq/ae4ffea04b66fb624b2fd7775c56144adf0f0d60/files/plugins/rabbit_stomp-2.3.1.ez
--------------------------------------------------------------------------------
/hiera.yaml:
--------------------------------------------------------------------------------
1 | ---
2 | version: 5
3 |
4 | defaults:
5 | datadir: 'data'
6 | data_hash: 'yaml_data'
7 |
8 | hierarchy:
9 | - name: 'Major Version'
10 | path: "os/%{facts.os.name}-%{facts.os.release.major}.yaml"
11 | - name: 'Distribution Name'
12 | path: "os/%{facts.os.name}.yaml"
13 | - name: 'Operating System Family'
14 | path: "family/%{facts.os.family}.yaml"
15 | - name: 'Common'
16 | path: 'common.yaml'
17 |
--------------------------------------------------------------------------------
/lib/facter/erl_ssl_path.rb:
--------------------------------------------------------------------------------
1 | # rubocop:disable Style/FrozenStringLiteralComment
2 |
3 | # Fact to get the ssl path for the erlang distribution in the current
4 | # system as described in the RabbitMQ docs [1].
5 | #
6 | # [1] https://www.rabbitmq.com/clustering-ssl.html
7 |
8 | Facter.add(:erl_ssl_path) do
9 | setcode do
10 | if Facter::Util::Resolution.which('erl')
11 | data = Facter::Core::Execution.execute("erl -eval 'io:format(\"~p\", [code:lib_dir(ssl, ebin)]),halt().' -noshell")
12 | # erl returns the string with quotes, strip them off
13 | data.gsub!(%r{\A"|"\Z}, '')
14 | end
15 | end
16 | end
17 | # rubocop:enable Style/FrozenStringLiteralComment
18 |
--------------------------------------------------------------------------------
/lib/facter/rabbitmq_clustername.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | Facter.add(:rabbitmq_clustername) do
4 | setcode do
5 | if Facter::Util::Resolution.which('rabbitmqctl')
6 | ret = nil
7 | cluster_status = Facter::Core::Execution.execute('rabbitmqctl -q cluster_status 2>&1')
8 | [%r!{cluster_name,<<"(\S+)">>}!, %r{^Cluster name: (\S+)$}].each do |r|
9 | if (data = r.match(cluster_status))
10 | ret = data[1]
11 | break
12 | end
13 | end
14 | end
15 | ret
16 | end
17 | end
18 |
--------------------------------------------------------------------------------
/lib/facter/rabbitmq_nodename.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | Facter.add(:rabbitmq_nodename) do
4 | setcode do
5 | if Facter::Util::Resolution.which('rabbitmqctl')
6 | rabbitmq_nodename = Facter::Core::Execution.execute('rabbitmqctl status 2>&1')
7 | begin
8 | %r{^Status of node '?([\w.-]+@[\w.-]+)'?}.match(rabbitmq_nodename)[1]
9 | rescue StandardError
10 | Facter.debug("Error: rabbitmq_nodename facter failed. Output was #{rabbitmq_nodename}")
11 | end
12 | end
13 | end
14 | end
15 |
--------------------------------------------------------------------------------
/lib/facter/rabbitmq_plugins_dirs.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | Facter.add(:rabbitmq_plugins_dirs) do
4 | setcode do
5 | if Facter::Util::Resolution.which('rabbitmqctl')
6 | rabbitmq_pluginsdirs_env = Facter::Core::Execution.execute("rabbitmqctl eval 'application:get_env(rabbit, plugins_dir).'")
7 | rabbitmq_plugins_dirs_match = %r{^\{ok,"(/.+/\w+)}.match(rabbitmq_pluginsdirs_env)
8 | rabbitmq_plugins_dirs_match[1].split(':') if rabbitmq_plugins_dirs_match
9 | end
10 | end
11 | end
12 |
--------------------------------------------------------------------------------
/lib/facter/rabbitmq_version.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | Facter.add(:rabbitmq_version) do
4 | setcode do
5 | if Facter::Util::Resolution.which('rabbitmqadmin')
6 | rabbitmq_version = Facter::Core::Execution.execute('rabbitmqadmin --version 2>&1')
7 | %r{^rabbitmqadmin ([\w.]+)}.match(rabbitmq_version).to_a[1]
8 | end
9 | end
10 | end
11 |
--------------------------------------------------------------------------------
/lib/puppet/provider/rabbitmq_binding/rabbitmqadmin.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | require 'json'
4 | require 'puppet'
5 | require 'digest'
6 |
7 | require File.expand_path(File.join(File.dirname(__FILE__), '..', 'rabbitmq_cli'))
8 | Puppet::Type.type(:rabbitmq_binding).provide(:rabbitmqadmin, parent: Puppet::Provider::RabbitmqCli) do
9 | desc 'Rabbitmqadmin provider for rabbitmq binding'
10 | confine feature: :posix
11 |
12 | # Without this, the composite namevar stuff doesn't work properly.
13 | mk_resource_methods
14 |
15 | def should_vhost
16 | @should_vhost || @should_vhost = resource[:vhost]
17 | end
18 |
19 | def self.all_vhosts
20 | vhosts = []
21 | rabbitmqctl_list('vhosts').split(%r{\n}).map do |vhost|
22 | vhosts.push(vhost)
23 | end
24 | vhosts
25 | end
26 |
27 | def self.all_bindings(vhost)
28 | rabbitmqctl_list('bindings', '-p', vhost, 'source_name', 'destination_name', 'destination_kind', 'routing_key', 'arguments').split(%r{\n})
29 | end
30 |
31 | def self.instances
32 | resources = []
33 | all_vhosts.each do |vhost|
34 | all_bindings(vhost).map do |line|
35 | source_name, destination_name, destination_type, routing_key, arguments = line.split(%r{\t})
36 | # Convert output of arguments from the rabbitmqctl command to a json string.
37 | if arguments.nil?
38 | arguments = '{}'
39 | else
40 | arguments = arguments.gsub(%r{^\[(.*)\]$}, '').gsub(%r{\{("(?:.|\\")*?"),}, '{\1:').gsub(%r{\},\{}, ',')
41 | arguments = '{}' if arguments == ''
42 | end
43 | hashed_name = Digest::SHA256.hexdigest format('%s@%s@%s@%s', source_name, destination_name, vhost, routing_key)
44 | next if source_name.empty?
45 |
46 | binding = {
47 | source: source_name,
48 | destination: destination_name,
49 | vhost: vhost,
50 | destination_type: destination_type,
51 | routing_key: routing_key,
52 | arguments: JSON.parse(arguments),
53 | ensure: :present,
54 | name: hashed_name
55 | }
56 | resources << new(binding) if binding[:name]
57 | end
58 | end
59 | resources
60 | end
61 |
62 | # see
63 | # https://github.com/puppetlabs/puppetlabs-netapp/blob/d0a655665463c69c932f835ba8756be32417a4e9/lib/puppet/provider/netapp_qtree/sevenmode.rb#L66-L73
64 | def self.prefetch(resources)
65 | bindings = instances
66 | resources.each do |name, res|
67 | if (provider = bindings.find { |binding| binding.source == res[:source] && binding.destination == res[:destination] && binding.vhost == res[:vhost] && binding.routing_key == res[:routing_key] })
68 | resources[name].provider = provider
69 | end
70 | end
71 | end
72 |
73 | def exists?
74 | @property_hash[:ensure] == :present
75 | end
76 |
77 | def create
78 | vhost_opt = should_vhost ? "--vhost=#{should_vhost}" : ''
79 | arguments = resource[:arguments]
80 | arguments = {} if arguments.nil?
81 | rabbitmqadmin('declare',
82 | 'binding',
83 | vhost_opt,
84 | "--user=#{resource[:user]}",
85 | "--password=#{resource[:password]}",
86 | '-c',
87 | '/etc/rabbitmq/rabbitmqadmin.conf',
88 | "source=#{resource[:source]}",
89 | "destination=#{resource[:destination]}",
90 | "arguments=#{arguments.to_json}",
91 | "routing_key=#{resource[:routing_key]}",
92 | "destination_type=#{resource[:destination_type]}")
93 | @property_hash[:ensure] = :present
94 | end
95 |
96 | def destroy
97 | vhost_opt = should_vhost ? "--vhost=#{should_vhost}" : ''
98 | rabbitmqadmin('delete', 'binding', vhost_opt, "--user=#{resource[:user]}", "--password=#{resource[:password]}", '-c', '/etc/rabbitmq/rabbitmqadmin.conf', "source=#{resource[:source]}", "destination_type=#{resource[:destination_type]}", "destination=#{resource[:destination]}", "properties_key=#{resource[:routing_key]}")
99 | @property_hash[:ensure] = :absent
100 | end
101 | end
102 |
--------------------------------------------------------------------------------
/lib/puppet/provider/rabbitmq_cli.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class Puppet::Provider::RabbitmqCli < Puppet::Provider
4 | initvars
5 |
6 | def self.append_to_path(dir)
7 | path = get_env 'PATH'
8 | # Don't append to the PATH if the directory is already in it. Otherwise, if
9 | # multiple providers run in the same process it may result in the
10 | # environment being modified multiple times.
11 | return if path.split(File::PATH_SEPARATOR).include? dir
12 |
13 | set_env 'PATH', [path, dir].join(File::PATH_SEPARATOR)
14 | end
15 | private_class_method :append_to_path
16 |
17 | # On most platforms, the RabbitMQ CLI programs are available in the PATH under
18 | # /usr/sbin. On some older platforms (CentOS 6), they are only available at
19 | # /usr/lib/rabbitmq/bin. We can't detect which because at the time this file
20 | # is evaluated, RabbitMQ might not yet be installed. However, if a command is
21 | # specified by name (instead of absolute path), Puppet searches the PATH
22 | # before each execution of the command. Append /usr/lib/rabbitmq/bin to the
23 | # end of the PATH so that Puppet will look there last at the time a command is
24 | # executed. This is the best I can come up with short of fragile meta-
25 | # programming with Puppet internals.
26 | append_to_path '/usr/lib/rabbitmq/bin'
27 |
28 | def self.home_tmp_command(name, path)
29 | has_command name, path do
30 | environment HOME: '/tmp', LC_ALL: 'en_US.UTF-8'
31 | end
32 | end
33 |
34 | home_tmp_command :rabbitmqctl, 'rabbitmqctl'
35 | home_tmp_command :rabbitmqplugins, 'rabbitmq-plugins'
36 |
37 | home_tmp_command :rabbitmqadmin, '/usr/local/bin/rabbitmqadmin'
38 |
39 | def self.rabbitmq_version
40 | return @rabbitmq_version if defined? @rabbitmq_version
41 |
42 | output = rabbitmqctl('-q', 'status')
43 | version = output.match(%r{RabbitMQ.*?([\d.]+)})
44 | @rabbitmq_version = version[1] if version
45 | @rabbitmq_version
46 | end
47 |
48 | def self.rabbitmqctl_list(resource, *opts)
49 | version = rabbitmq_version
50 | list_opts =
51 | if version && Puppet::Util::Package.versioncmp(version, '3.7.9') >= 0
52 | ['-q', '--no-table-headers']
53 | else
54 | ['-q']
55 | end
56 | rabbitmqctl("list_#{resource}", *list_opts, *opts)
57 | rescue Puppet::MissingCommand
58 | # rabbitmqctl is not present. Normally we would have installed a package
59 | # that provides rabbitmqctl by now, but if we're running under --noop or
60 | # with a restrictive set of tags, the package may not have been installed.
61 | # Return an empty string to avoid error. This may give false positives for
62 | # resources under --noop!
63 | Puppet.debug('rabbitmqctl command not found; assuming rabbitmq is not installed')
64 | ''
65 | end
66 |
67 | def self.rabbitmq_running
68 | rabbitmqctl('-q', 'status')
69 | true
70 | rescue Puppet::ExecutionFailure, Timeout::Error
71 | false
72 | end
73 |
74 | # Retry the given code block 'count' retries or until the
75 | # command succeeds. Use 'step' delay between retries.
76 | # Limit each query time by 'timeout'.
77 | # For example:
78 | # users = self.class.run_with_retries { rabbitmqctl 'list_users' }
79 | def self.run_with_retries(count = 30, step = 6, timeout = 10, &block)
80 | count.times do |_n|
81 | output = Timeout.timeout(timeout, &block)
82 | rescue Puppet::ExecutionFailure, Timeout::Error
83 | Puppet.debug 'Command failed, retrying'
84 | sleep step
85 | else
86 | Puppet.debug 'Command succeeded'
87 | return output
88 | end
89 | raise Puppet::Error, "Command is still failing after #{count * step} seconds expired!"
90 | end
91 |
92 | def self.define_instance_method(name)
93 | return if method_defined?(name)
94 |
95 | define_method(name) do |*args, &block|
96 | self.class.send(name, *args, &block)
97 | end
98 | end
99 | private_class_method :define_instance_method
100 |
101 | define_instance_method :rabbitmqctl_list
102 | define_instance_method :run_with_retries
103 | end
104 |
--------------------------------------------------------------------------------
/lib/puppet/provider/rabbitmq_cluster/rabbitmqctl.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | require File.expand_path(File.join(File.dirname(__FILE__), '..', 'rabbitmq_cli'))
4 | Puppet::Type.type(:rabbitmq_cluster).provide(
5 | :rabbitmqctl,
6 | parent: Puppet::Provider::RabbitmqCli
7 | ) do
8 | desc 'Rabbitmqctl provider for rabbitmq cluster'
9 | confine feature: :posix
10 |
11 | def exists?
12 | cluster_name == @resource[:name].to_s
13 | end
14 |
15 | def create
16 | storage_type = @resource[:node_disc_type].to_s
17 |
18 | init_node = @resource[:init_node].to_s.gsub(%r{^.*@}, '')
19 | local_node = @resource[:local_node].to_s.gsub(%r{^.*@}, '')
20 |
21 | if local_node == init_node || [Facter.value(:networking)['hostname'], Facter.value(:networking)['fqdn']].include?(init_node)
22 | return rabbitmqctl('set_cluster_name', @resource[:name]) unless cluster_name == resource[:name].to_s
23 | else
24 | rabbitmqctl('stop_app')
25 | rabbitmqctl('join_cluster', "rabbit@#{init_node}", "--#{storage_type}")
26 | rabbitmqctl('start_app')
27 | end
28 | end
29 |
30 | def destroy
31 | rabbitmqctl('stop_app')
32 | rabbitmqctl('reset')
33 | rabbitmqctl('start_app')
34 | end
35 |
36 | def cluster_name
37 | cluster_status = rabbitmqctl('-q', 'cluster_status')
38 | [%r!{cluster_name,<<"(\S+)">>}!, %r{^Cluster name: (\S+)$}].each do |r|
39 | if (data = r.match(cluster_status))
40 | return data[1]
41 | end
42 | end
43 | end
44 | end
45 |
--------------------------------------------------------------------------------
/lib/puppet/provider/rabbitmq_erlang_cookie/ruby.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | require 'puppet'
4 | require 'set'
5 | Puppet::Type.type(:rabbitmq_erlang_cookie).provide(:ruby) do
6 | desc 'Ruby provider for rabbitmq erlang cookie'
7 | confine feature: :posix
8 |
9 | def exists?
10 | # Hack to prevent the create method from being called.
11 | # We never need to create or destroy this resource, only change its value
12 | true
13 | end
14 |
15 | def content=(value)
16 | raise('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.') unless resource[:force] == :true # Danger!
17 |
18 | Puppet::Type.type(:service).new(name: resource[:service_name]).provider.stop
19 | FileUtils.rm_rf("#{resource[:rabbitmq_home]}#{File::SEPARATOR}mnesia")
20 | File.open(resource[:path], 'w') do |cookie|
21 | cookie.chmod(0o400)
22 | cookie.write(value)
23 | end
24 | FileUtils.chown(resource[:rabbitmq_user], resource[:rabbitmq_group], resource[:path])
25 | end
26 |
27 | def content
28 | if File.exist?(resource[:path])
29 | File.read(resource[:path])
30 | else
31 | ''
32 | end
33 | end
34 | end
35 |
--------------------------------------------------------------------------------
/lib/puppet/provider/rabbitmq_exchange/rabbitmqadmin.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | require 'puppet'
4 | require File.expand_path(File.join(File.dirname(__FILE__), '..', 'rabbitmq_cli'))
5 | Puppet::Type.type(:rabbitmq_exchange).provide(:rabbitmqadmin, parent: Puppet::Provider::RabbitmqCli) do
6 | desc 'Rabbitmqadmin provider for rabbitmq exchange'
7 | confine feature: :posix
8 |
9 | def should_vhost
10 | @should_vhost || @should_vhost = resource[:name].split('@')[1]
11 | end
12 |
13 | def self.all_vhosts
14 | run_with_retries { rabbitmqctl_list('vhosts') }.split(%r{\n})
15 | end
16 |
17 | def self.all_exchanges(vhost)
18 | exchange_list = run_with_retries do
19 | rabbitmqctl_list('exchanges', '-p', vhost, 'name', 'type', 'internal', 'durable', 'auto_delete', 'arguments')
20 | end
21 | exchange_list.split(%r{\n}).grep_v(%r{^federation:})
22 | end
23 |
24 | def self.instances
25 | resources = []
26 | all_vhosts.each do |vhost|
27 | all_exchanges(vhost).each do |line|
28 | name, type, internal, durable, auto_delete, arguments = line.split
29 | if type.nil?
30 | # if name is empty, it will wrongly get the type's value.
31 | # This way type will get the correct value
32 | type = name
33 | name = ''
34 | end
35 | # Convert output of arguments from the rabbitmqctl command to a json string.
36 | if arguments.nil?
37 | arguments = '{}'
38 | else
39 | arguments = arguments.gsub(%r{^\[(.*)\]$}, '').gsub(%r{\{("(?:.|\\")*?"),}, '{\1:').gsub(%r{\},\{}, ',')
40 | arguments = '{}' if arguments == ''
41 | end
42 | exchange = {
43 | type: type,
44 | ensure: :present,
45 | internal: internal,
46 | durable: durable,
47 | auto_delete: auto_delete,
48 | name: format('%s@%s', name, vhost),
49 | arguments: JSON.parse(arguments)
50 | }
51 | resources << new(exchange) if exchange[:type]
52 | end
53 | end
54 | resources
55 | end
56 |
57 | def self.prefetch(resources)
58 | packages = instances
59 | resources.each_key do |name|
60 | if (provider = packages.find { |pkg| pkg.name == name })
61 | resources[name].provider = provider
62 | end
63 | end
64 | end
65 |
66 | def exists?
67 | @property_hash[:ensure] == :present
68 | end
69 |
70 | def create
71 | vhost_opt = should_vhost ? "--vhost=#{should_vhost}" : ''
72 | name = resource[:name].split('@')[0]
73 | arguments = resource[:arguments]
74 | arguments = {} if arguments.nil?
75 | cmd = ['declare', 'exchange', vhost_opt, "--user=#{resource[:user]}", "--password=#{resource[:password]}", "name=#{name}", "type=#{resource[:type]}"]
76 | cmd << "internal=#{resource[:internal]}"
77 | cmd << "durable=#{resource[:durable]}"
78 | cmd << "auto_delete=#{resource[:auto_delete]}"
79 | cmd += ["arguments=#{arguments.to_json}", '-c', '/etc/rabbitmq/rabbitmqadmin.conf']
80 | rabbitmqadmin(*cmd)
81 | @property_hash[:ensure] = :present
82 | end
83 |
84 | def destroy
85 | vhost_opt = should_vhost ? "--vhost=#{should_vhost}" : ''
86 | name = resource[:name].split('@')[0]
87 | rabbitmqadmin('delete', 'exchange', vhost_opt, "--user=#{resource[:user]}", "--password=#{resource[:password]}", "name=#{name}", '-c', '/etc/rabbitmq/rabbitmqadmin.conf')
88 | @property_hash[:ensure] = :absent
89 | end
90 | end
91 |
--------------------------------------------------------------------------------
/lib/puppet/provider/rabbitmq_parameter/rabbitmqctl.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | require 'json'
4 | require 'puppet/util/package'
5 |
6 | require File.expand_path(File.join(File.dirname(__FILE__), '..', 'rabbitmq_cli'))
7 | Puppet::Type.type(:rabbitmq_parameter).provide(:rabbitmqctl, parent: Puppet::Provider::RabbitmqCli) do
8 | desc 'Rabbitmqctl provider for rabbitmq parameter'
9 | confine feature: :posix
10 |
11 | mk_resource_methods
12 |
13 | def initialize(value = {})
14 | super(value)
15 | @property_flush = {}
16 | end
17 |
18 | def self.all_vhosts
19 | rabbitmqctl_list('vhosts').split(%r{\n})
20 | end
21 |
22 | def self.all_parameters(vhost)
23 | rabbitmqctl_list('parameters', '-p', vhost).split(%r{\n})
24 | end
25 |
26 | def self.instances
27 | resources = []
28 | all_vhosts.each do |vhost|
29 | all_parameters(vhost).map do |line|
30 | raise Puppet::Error, "cannot parse line from list_parameter:#{line}" unless line =~ %r{^(\S+)\s+(\S+)\s+(\S+)$}
31 |
32 | parameter = {
33 | ensure: :present,
34 | component_name: Regexp.last_match(1),
35 | name: format('%s@%s', Regexp.last_match(2), vhost),
36 | value: JSON.parse(Regexp.last_match(3))
37 | }
38 | resources << new(parameter)
39 | end
40 | end
41 | resources
42 | end
43 |
44 | def self.prefetch(resources)
45 | packages = instances
46 | resources.each_key do |name|
47 | Puppet.info "Calling prefetch: #{name}"
48 | if (provider = packages.find { |pkg| pkg.name == name })
49 | resources[name].provider = provider
50 | end
51 | end
52 | end
53 |
54 | def exists?
55 | @property_hash[:ensure] == :present
56 | end
57 |
58 | def create
59 | @property_flush[:ensure] = :present
60 | set_parameter
61 | end
62 |
63 | def destroy
64 | @property_flush[:ensure] = :absent
65 | set_parameter
66 | end
67 |
68 | def set_parameter
69 | vhost = resource[:name].rpartition('@').last
70 | key = resource[:name].rpartition('@').first
71 |
72 | if @property_flush[:ensure] == :absent
73 | rabbitmqctl('clear_parameter', '-p', vhost, resource[:component_name] || component_name, key)
74 | else
75 | rabbitmqctl('set_parameter', '-p', vhost, resource[:component_name], key, resource[:value].to_json)
76 | end
77 | end
78 | end
79 |
--------------------------------------------------------------------------------
/lib/puppet/provider/rabbitmq_plugin/rabbitmqplugins.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | require 'puppet/util/package'
4 |
5 | require File.expand_path(File.join(File.dirname(__FILE__), '..', 'rabbitmq_cli'))
6 | Puppet::Type.type(:rabbitmq_plugin).provide(:rabbitmqplugins, parent: Puppet::Provider::RabbitmqCli) do
7 | desc 'Rabbitmqplugins provider for rabbitmq plugin'
8 | confine feature: :posix
9 |
10 | def self.plugin_list
11 | list_str = run_with_retries do
12 | # Pass in -e to list both implicitly and explicitly enabled plugins.
13 | # If you pass in -E instead, then only explicitly enabled plugins are listed.
14 | # Implicitly enabled plugins are those that were enabled as a dependency of another plugin/
15 | # If we do not pass in -e then the order if plugin installation matters within the puppet
16 | # code. Example, if Plugin A depends on Plugin B and we install Plugin B first it will
17 | # implicitly enable Plugin A. Then when we go to run Puppet a second time without the
18 | # -e parameter, we won't see Plugin A as being enabled so we'll try to install it again.
19 | # To preserve idempotency we should get all enabled plugins regardless of implicitly or
20 | # explicitly enabled.
21 | rabbitmqplugins('list', '-e', '-m')
22 | rescue Puppet::MissingCommand
23 | # See note about Puppet::MissingCommand in:
24 | # lib/puppet/provider/rabbitmq_cli.rb
25 | Puppet.debug('rabbitmqplugins command not found; assuming rabbitmq is not installed')
26 | ''
27 | end
28 | # Split by newline.
29 | lines = list_str.split(%r{\n})
30 | # Return only lines that are single words because sometimes RabbitMQ likes to output
31 | # information messages. Suppressing those messages via CLI flags is inconsistent between
32 | # versions, so this this regex removes those message without having to use painful
33 | # version switches.
34 | lines.grep(%r{^(\S+)$})
35 | end
36 |
37 | def self.instances
38 | plugin_list.map do |line|
39 | raise Puppet::Error, "Cannot parse invalid plugins line: #{line}" unless line =~ %r{^(\S+)$}
40 |
41 | new(name: Regexp.last_match(1))
42 | end
43 | end
44 |
45 | def create
46 | cmd = ['enable', resource[:name]]
47 | # rabbitmq>=3.4.0 - check if node running, if not, ignore this option
48 | cmd << "--#{resource[:mode]}" if self.class.rabbitmq_running && Puppet::Util::Package.versioncmp(self.class.rabbitmq_version, '3.4') >= 0 && resource[:mode] != :best
49 |
50 | if resource[:umask].nil?
51 | rabbitmqplugins(*cmd)
52 | else
53 | Puppet::Util.withumask(resource[:umask]) { rabbitmqplugins(*cmd) }
54 | end
55 | end
56 |
57 | def destroy
58 | rabbitmqplugins('disable', resource[:name])
59 | end
60 |
61 | def exists?
62 | self.class.plugin_list.include? resource[:name]
63 | end
64 | end
65 |
--------------------------------------------------------------------------------
/lib/puppet/provider/rabbitmq_policy/rabbitmqctl.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | require 'json'
4 | require 'puppet/util/package'
5 |
6 | require File.expand_path(File.join(File.dirname(__FILE__), '..', 'rabbitmq_cli'))
7 | Puppet::Type.type(:rabbitmq_policy).provide(:rabbitmqctl, parent: Puppet::Provider::RabbitmqCli) do
8 | desc 'Rabbitmqctl provider for rabbitmq policy'
9 | confine feature: :posix
10 |
11 | # cache policies
12 | def self.policies(vhost, name)
13 | @policies ||= {}
14 | unless @policies[vhost]
15 | @policies[vhost] = {}
16 | policy_list = run_with_retries do
17 | rabbitmqctl_list('policies', '-p', vhost)
18 | end
19 |
20 | # rabbitmq<3.2 does not support the applyto field
21 | # 1 2 3? 4 5 6
22 | # / ha-all all .* {"ha-mode":"all","ha-sync-mode":"automatic"} 0 << This is for RabbitMQ v < 3.7.0
23 | # / ha-all .* all {"ha-mode":"all","ha-sync-mode":"automatic"} 0 << This is for RabbitMQ v >= 3.7.0
24 | if Puppet::Util::Package.versioncmp(rabbitmq_version, '3.7') >= 0
25 | regex = %r{^(\S+)\s+(\S+)\s+(\S+)\s+(all|exchanges|(?:classic_|quorum_)?queues|streams)?\s+(\S+)\s+(\d+)$}
26 | applyto_index = 4
27 | pattern_index = 3
28 | else
29 | regex = %r{^(\S+)\s+(\S+)\s+(all|exchanges|queues)?\s*(\S+)\s+(\S+)\s+(\d+)$}
30 | applyto_index = 3
31 | pattern_index = 4
32 | end
33 |
34 | policy_list.split(%r{\n}).each do |line|
35 | raise Puppet::Error, "cannot parse line from list_policies:#{line}" unless line =~ regex
36 |
37 | n = Regexp.last_match(2)
38 | applyto = Regexp.last_match(applyto_index) || 'all'
39 | priority = Regexp.last_match(6)
40 | definition = JSON.parse(Regexp.last_match(5))
41 | # be aware that the gsub will reset the captures
42 | # from the regexp above
43 | pattern = Regexp.last_match(pattern_index).to_s.gsub(%r{\\\\}, '\\')
44 |
45 | @policies[vhost][n] = {
46 | applyto: applyto,
47 | pattern: pattern,
48 | definition: definition,
49 | priority: priority
50 | }
51 | end
52 | end
53 | @policies[vhost][name]
54 | end
55 |
56 | def policies(vhost, name)
57 | self.class.policies(vhost, name)
58 | end
59 |
60 | def should_policy
61 | @should_policy ||= resource[:name].rpartition('@').first
62 | end
63 |
64 | def should_vhost
65 | @should_vhost ||= resource[:name].rpartition('@').last
66 | end
67 |
68 | def create
69 | set_policy
70 | end
71 |
72 | def destroy
73 | rabbitmqctl('clear_policy', '-p', should_vhost, should_policy)
74 | end
75 |
76 | def exists?
77 | policies(should_vhost, should_policy)
78 | end
79 |
80 | def pattern
81 | policies(should_vhost, should_policy)[:pattern]
82 | end
83 |
84 | def pattern=(_pattern)
85 | set_policy
86 | end
87 |
88 | def applyto
89 | policies(should_vhost, should_policy)[:applyto]
90 | end
91 |
92 | def applyto=(_applyto)
93 | set_policy
94 | end
95 |
96 | def definition
97 | policies(should_vhost, should_policy)[:definition]
98 | end
99 |
100 | def definition=(_definition)
101 | set_policy
102 | end
103 |
104 | def priority
105 | policies(should_vhost, should_policy)[:priority]
106 | end
107 |
108 | def priority=(_priority)
109 | set_policy
110 | end
111 |
112 | def set_policy
113 | return if @set_policy
114 |
115 | @set_policy = true
116 | resource[:applyto] ||= applyto
117 | resource[:definition] ||= definition
118 | resource[:pattern] ||= pattern
119 | resource[:priority] ||= priority
120 | # rabbitmq>=3.2.0
121 | if Puppet::Util::Package.versioncmp(self.class.rabbitmq_version, '3.2.0') >= 0
122 | rabbitmqctl(
123 | 'set_policy',
124 | '-p', should_vhost,
125 | '--priority', resource[:priority],
126 | '--apply-to', resource[:applyto].to_s,
127 | should_policy,
128 | resource[:pattern],
129 | resource[:definition].to_json
130 | )
131 | else
132 | rabbitmqctl(
133 | 'set_policy',
134 | '-p', should_vhost,
135 | should_policy,
136 | resource[:pattern],
137 | resource[:definition].to_json,
138 | resource[:priority]
139 | )
140 | end
141 | end
142 | end
143 |
--------------------------------------------------------------------------------
/lib/puppet/provider/rabbitmq_queue/rabbitmqadmin.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | require 'json'
4 | require 'puppet'
5 |
6 | require File.expand_path(File.join(File.dirname(__FILE__), '..', 'rabbitmq_cli'))
7 | Puppet::Type.type(:rabbitmq_queue).provide(:rabbitmqadmin, parent: Puppet::Provider::RabbitmqCli) do
8 | desc 'Rabbitmqadmin provider for rabbitmq queue'
9 | confine feature: :posix
10 |
11 | def should_vhost
12 | @should_vhost || @should_vhost = resource[:name].rpartition('@').last
13 | end
14 |
15 | def self.all_vhosts
16 | rabbitmqctl_list('vhosts').split(%r{\n})
17 | end
18 |
19 | def self.all_queues(vhost)
20 | rabbitmqctl_list('queues', '-p', vhost, 'name', 'durable', 'auto_delete', 'arguments').split(%r{\n})
21 | end
22 |
23 | def self.instances
24 | resources = []
25 | all_vhosts.each do |vhost|
26 | all_queues(vhost).map do |line|
27 | next if line =~ %r{^federation:}
28 |
29 | name, durable, auto_delete, arguments = line.split("\t")
30 | # Convert output of arguments from the rabbitmqctl command to a json string.
31 | if arguments.nil?
32 | arguments = '{}'
33 | else
34 | arguments = arguments.gsub(%r{^\[(.*)\]$}, '').gsub(%r{\{("(?:.|\\")*?"),}, '{\1:').gsub(%r{\},\{}, ',')
35 | arguments = '{}' if arguments == ''
36 | end
37 | queue = {
38 | durable: durable,
39 | auto_delete: auto_delete,
40 | arguments: JSON.parse(arguments),
41 | ensure: :present,
42 | name: format('%s@%s', name, vhost)
43 | }
44 | resources << new(queue) if queue[:name]
45 | end
46 | end
47 | resources
48 | end
49 |
50 | def self.prefetch(resources)
51 | packages = instances
52 | resources.each_key do |name|
53 | if (provider = packages.find { |pkg| pkg.name == name })
54 | resources[name].provider = provider
55 | end
56 | end
57 | end
58 |
59 | def exists?
60 | @property_hash[:ensure] == :present
61 | end
62 |
63 | def create
64 | vhost_opt = should_vhost ? "--vhost=#{should_vhost}" : ''
65 | name = resource[:name].rpartition('@').first
66 | arguments = resource[:arguments]
67 | arguments = {} if arguments.nil?
68 | rabbitmqadmin('declare',
69 | 'queue',
70 | vhost_opt,
71 | "--user=#{resource[:user]}",
72 | "--password=#{resource[:password]}",
73 | '-c',
74 | '/etc/rabbitmq/rabbitmqadmin.conf',
75 | "name=#{name}",
76 | "durable=#{resource[:durable]}",
77 | "auto_delete=#{resource[:auto_delete]}",
78 | "arguments=#{arguments.to_json}")
79 | @property_hash[:ensure] = :present
80 | end
81 |
82 | def destroy
83 | vhost_opt = should_vhost ? "--vhost=#{should_vhost}" : ''
84 | name = resource[:name].rpartition('@').first
85 | rabbitmqadmin('delete', 'queue', vhost_opt, "--user=#{resource[:user]}", "--password=#{resource[:password]}", '-c', '/etc/rabbitmq/rabbitmqadmin.conf', "name=#{name}")
86 | @property_hash[:ensure] = :absent
87 | end
88 | end
89 |
--------------------------------------------------------------------------------
/lib/puppet/provider/rabbitmq_user/rabbitmqctl.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | require File.expand_path(File.join(File.dirname(__FILE__), '..', 'rabbitmq_cli'))
4 | Puppet::Type.type(:rabbitmq_user).provide(
5 | :rabbitmqctl,
6 | parent: Puppet::Provider::RabbitmqCli
7 | ) do
8 | desc 'Rabbitmqctl provider for rabbitmq user'
9 | confine feature: :posix
10 |
11 | def initialize(value = {})
12 | super(value)
13 | @property_flush = {}
14 | end
15 |
16 | def self.instances
17 | user_list = run_with_retries do
18 | rabbitmqctl_list('users')
19 | end
20 |
21 | user_list.split(%r{\n}).map do |line|
22 | raise Puppet::Error, "Cannot parse invalid user line: #{line}" unless line =~ %r{^(\S+)\s+\[(.*?)\]$}
23 |
24 | user = Regexp.last_match(1)
25 | tags = Regexp.last_match(2).split(%r{,\s*})
26 | new(
27 | ensure: :present,
28 | name: user,
29 | tags: tags
30 | )
31 | end
32 | end
33 |
34 | def self.prefetch(resources)
35 | users = instances
36 | resources.each_key do |user|
37 | if (provider = users.find { |u| u.name == user })
38 | resources[user].provider = provider
39 | end
40 | end
41 | end
42 |
43 | def exists?
44 | @property_hash[:ensure] == :present
45 | end
46 |
47 | def create
48 | # Fail here (rather than a validate block in the type) if password is not
49 | # set, so that "puppet resource" still works.
50 | raise Puppet::Error, "Password is a required parameter for rabbitmq_user (user: #{name})" if @resource[:password].nil?
51 |
52 | rabbitmqctl('add_user', @resource[:name], @resource[:password])
53 |
54 | tags = @resource[:tags]
55 | tags << admin_tag if @resource[:admin] == :true
56 | rabbitmqctl('set_user_tags', @resource[:name], tags) unless tags.empty?
57 |
58 | @property_hash[:ensure] = :present
59 | end
60 |
61 | def destroy
62 | rabbitmqctl('delete_user', @resource[:name])
63 | @property_hash[:ensure] = :absent
64 | end
65 |
66 | def password=(password)
67 | rabbitmqctl('change_password', @resource[:name], password)
68 | end
69 |
70 | def password; end
71 |
72 | def check_password(password)
73 | check_access_control = [
74 | 'rabbit_access_control:check_user_pass_login(',
75 | %[list_to_binary("#{@resource[:name]}"), ],
76 | %[list_to_binary("#{password.to_s.gsub('"', '\\"')}")).]
77 | ]
78 |
79 | response = rabbitmqctl('eval', check_access_control.join)
80 | !response.include? 'refused'
81 | end
82 |
83 | def tags
84 | # do not expose the administrator tag for admins
85 | @property_hash[:tags].reject { |tag| tag == admin_tag }
86 | end
87 |
88 | def tags=(tags)
89 | @property_flush[:tags] = tags
90 | end
91 |
92 | def admin
93 | usertags = get_user_tags
94 | 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?)" unless usertags
95 |
96 | (:true if usertags.include?('administrator')) || :false
97 | end
98 |
99 | def admin=(state)
100 | if state == :true
101 | make_user_admin
102 | else
103 | usertags = get_user_tags
104 | usertags.delete('administrator')
105 | rabbitmqctl('set_user_tags', resource[:name], usertags.entries.sort)
106 | end
107 | end
108 |
109 | def admin
110 | @property_hash[:tags].include?(admin_tag) ? :true : :false
111 | end
112 |
113 | def admin=(state)
114 | @property_flush[:admin] = state
115 | end
116 |
117 | def flush
118 | return if @property_flush.empty?
119 |
120 | tags = @property_flush[:tags] || @resource[:tags]
121 | tags << admin_tag if @resource[:admin] == :true
122 | rabbitmqctl('set_user_tags', @resource[:name], tags)
123 | @property_flush.clear
124 | end
125 |
126 | private
127 |
128 | def admin_tag
129 | 'administrator'
130 | end
131 | end
132 |
--------------------------------------------------------------------------------
/lib/puppet/provider/rabbitmq_user_permissions/rabbitmqctl.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | require File.expand_path(File.join(File.dirname(__FILE__), '..', 'rabbitmq_cli'))
4 | Puppet::Type.type(:rabbitmq_user_permissions).provide(:rabbitmqctl, parent: Puppet::Provider::RabbitmqCli) do
5 | desc 'Rabbitmqctl provider for rabbitmq user permissions'
6 | confine feature: :posix
7 |
8 | # cache users permissions
9 | def self.users(name, vhost)
10 | @users ||= {}
11 | unless @users[name]
12 | @users[name] = {}
13 | user_permission_list = run_with_retries do
14 | rabbitmqctl_list('user_permissions', name)
15 | end
16 | user_permission_list.split(%r{\n}).each do |line|
17 | line = strip_backslashes(line)
18 | raise Puppet::Error, "cannot parse line from list_user_permissions:#{line}" unless line =~ %r{^(\S+)\s+(\S*)\s+(\S*)\s+(\S*)$}
19 |
20 | @users[name][Regexp.last_match(1)] =
21 | { configure: Regexp.last_match(2), read: Regexp.last_match(4), write: Regexp.last_match(3) }
22 | end
23 | end
24 | @users[name][vhost]
25 | end
26 |
27 | def users(name, vhost)
28 | self.class.users(name, vhost)
29 | end
30 |
31 | def should_user
32 | @should_user || @should_user = resource[:name].split('@')[0]
33 | end
34 |
35 | def should_vhost
36 | @should_vhost || @should_vhost = resource[:name].split('@')[1]
37 | end
38 |
39 | def create
40 | resource[:configure_permission] ||= "''"
41 | resource[:read_permission] ||= "''"
42 | resource[:write_permission] ||= "''"
43 | rabbitmqctl('set_permissions', '-p', should_vhost, should_user, resource[:configure_permission], resource[:write_permission], resource[:read_permission])
44 | end
45 |
46 | def destroy
47 | rabbitmqctl('clear_permissions', '-p', should_vhost, should_user)
48 | end
49 |
50 | # I am implementing prefetching in exists b/c I need to be sure
51 | # that the rabbitmq package is installed before I make this call.
52 | def exists?
53 | users(should_user, should_vhost)
54 | end
55 |
56 | def configure_permission
57 | users(should_user, should_vhost)[:configure]
58 | end
59 |
60 | def configure_permission=(_perm)
61 | set_permissions
62 | end
63 |
64 | def read_permission
65 | users(should_user, should_vhost)[:read]
66 | end
67 |
68 | def read_permission=(_perm)
69 | set_permissions
70 | end
71 |
72 | def write_permission
73 | users(should_user, should_vhost)[:write]
74 | end
75 |
76 | def write_permission=(_perm)
77 | set_permissions
78 | end
79 |
80 | # implement memoization so that we only call set_permissions once
81 | def set_permissions
82 | return if @permissions_set
83 |
84 | @permissions_set = true
85 | resource[:configure_permission] ||= configure_permission
86 | resource[:read_permission] ||= read_permission
87 | resource[:write_permission] ||= write_permission
88 | rabbitmqctl(
89 | 'set_permissions',
90 | '-p', should_vhost,
91 | should_user,
92 | resource[:configure_permission],
93 | resource[:write_permission],
94 | resource[:read_permission]
95 | )
96 | end
97 |
98 | def self.strip_backslashes(string)
99 | # See: https://github.com/rabbitmq/rabbitmq-server/blob/v1_7/docs/rabbitmqctl.1.pod#output-escaping
100 | string.gsub(%r{\\\\}, '\\')
101 | end
102 | end
103 |
--------------------------------------------------------------------------------
/lib/puppet/provider/rabbitmq_vhost/rabbitmqctl.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | require File.expand_path(File.join(File.dirname(__FILE__), '..', 'rabbitmq_cli'))
4 | Puppet::Type.type(:rabbitmq_vhost).provide(
5 | :rabbitmqctl,
6 | parent: Puppet::Provider::RabbitmqCli
7 | ) do
8 | desc 'Rabbitmqctl provider for rabbitmq vhost'
9 | confine feature: :posix
10 |
11 | def self.prefetch(resources)
12 | instances.each do |prov|
13 | if (resource = resources[prov.name])
14 | resource.provider = prov
15 | end
16 | end
17 | end
18 |
19 | # To maintain compatibility with older versions of RabbitMQ,
20 | # we only deal with vhost metadata >= version 3.11.0
21 | def self.supports_metadata?
22 | Puppet::Util::Package.versioncmp(rabbitmq_version, '3.11') >= 0
23 | rescue Puppet::MissingCommand
24 | # See comment on the definition of rabbitmqctl_list in rabbitmqctl_cli.rb;
25 | # the same rationale applies here.
26 | Puppet.debug('supports_metadata?: rabbitmqctl command not found; assuming rabbitmq is not installed')
27 | false
28 | end
29 |
30 | def supports_metadata?
31 | self.class.supports_metadata?
32 | end
33 |
34 | def self.vhost_list
35 | run_with_retries do
36 | if supports_metadata?
37 | rabbitmqctl_list('vhosts', 'name,description,default_queue_type,tags', '-s')
38 | else
39 | rabbitmqctl_list('vhosts')
40 | end
41 | end
42 | end
43 |
44 | def self.instances
45 | vhost_list.split(%r{\n}).map do |line|
46 | if supports_metadata?
47 | raise Puppet::Error, "Cannot parse invalid vhost line: #{line}" unless \
48 | (matches = line.match(%r{^(\S+)\t+(.*?)\t+(undefined|quorum|classic|stream)?\t+\[(.*?)\]$}i))
49 |
50 | name, description, default_queue_type, tags = matches.captures
51 | # RMQ returns 'undefined' as default_queue_type if it has never been set
52 | default_queue_type = nil if default_queue_type == 'undefined'
53 | new(ensure: :present, name: name, description: description, default_queue_type: default_queue_type, tags: tags.split(%r{,\s*}))
54 | else
55 | raise Puppet::Error, "Cannot parse invalid vhost line: #{line}" unless line =~ %r{^(\S+)$}
56 |
57 | new(ensure: :present, name: Regexp.last_match(1))
58 | end
59 | end
60 | end
61 |
62 | def create
63 | rabbitmqctl('add_vhost', *params)
64 | end
65 |
66 | def params
67 | params = [resource[:name]]
68 | if supports_metadata?
69 | params << ['--description', resource[:description]] if resource[:description]
70 | params << ['--default-queue-type', resource[:default_queue_type]] if resource[:default_queue_type] && resource[:default_queue_type] != 'undefined'
71 | params << ['--tags', resource[:tags].join(',')] if resource[:tags]
72 | end
73 | params
74 | end
75 |
76 | def description
77 | @property_hash[:description]
78 | end
79 |
80 | def tags
81 | @property_hash[:tags]
82 | end
83 |
84 | def default_queue_type
85 | @property_hash[:default_queue_type]
86 | end
87 |
88 | def tags=(tags)
89 | @property_hash[:tags] = tags
90 | end
91 |
92 | def description=(value)
93 | @property_hash[:description] = value
94 | end
95 |
96 | def default_queue_type=(value)
97 | @property_hash[:default_queue_type] = value
98 | end
99 |
100 | def flush
101 | return if @property_hash.empty? || !supports_metadata? || !exists?
102 |
103 | params = [resource[:name]]
104 | params << ['--description', @property_hash[:description]] if @property_hash[:description]
105 | params << ['--default-queue-type', @property_hash[:default_queue_type]] if @property_hash[:default_queue_type]
106 | params << ['--tags', @property_hash[:tags].join(',')] if @property_hash[:tags]
107 | rabbitmqctl('update_vhost_metadata', *params)
108 | end
109 |
110 | def destroy
111 | rabbitmqctl('delete_vhost', resource[:name])
112 | end
113 |
114 | def exists?
115 | run_with_retries { rabbitmqctl_list('vhosts') }.split(%r{\n}).include? resource[:name]
116 | end
117 | end
118 |
--------------------------------------------------------------------------------
/lib/puppet/type/rabbitmq_binding.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | Puppet::Type.newtype(:rabbitmq_binding) do
4 | desc <<~DESC
5 | Native type for managing rabbitmq bindings
6 |
7 | @example Create a rabbitmq_binding
8 | rabbitmq_binding { 'myexchange@myqueue@myvhost':
9 | user => 'dan',
10 | password => 'bar',
11 | destination_type => 'queue',
12 | routing_key => '#',
13 | arguments => {},
14 | ensure => present,
15 | }
16 |
17 | @example Create bindings with same source / destination / vhost but different routing key using individual parameters
18 | rabbitmq_binding { 'binding 1':
19 | ensure => present,
20 | source => 'myexchange',
21 | destination => 'myqueue',
22 | vhost => 'myvhost',
23 | user => 'dan',
24 | password => 'bar',
25 | destination_type => 'queue',
26 | routing_key => 'key1',
27 | arguments => {},
28 | }
29 |
30 | rabbitmq_binding { 'binding 2':
31 | ensure => present,
32 | source => 'myexchange',
33 | destination => 'myqueue',
34 | vhost => 'myvhost',
35 | user => 'dan',
36 | password => 'bar',
37 | destination_type => 'queue',
38 | routing_key => 'key2',
39 | arguments => {},
40 | }
41 | DESC
42 |
43 | ensurable do
44 | desc 'Whether the resource should be present or absent'
45 | defaultto(:present)
46 | newvalue(:present) do
47 | provider.create
48 | end
49 | newvalue(:absent) do
50 | provider.destroy
51 | end
52 | end
53 |
54 | # Match patterns without '@' as arbitrary names; match patterns with
55 | # src@destination@vhost to their named params for backwards compatibility.
56 | def self.title_patterns
57 | [
58 | [
59 | %r{(^([^@]*)$)}m,
60 | [
61 | [:name]
62 | ]
63 | ],
64 | [
65 | %r{^((\S+)@(\S+)@(\S+))$}m,
66 | [
67 | [:name],
68 | [:source],
69 | [:destination],
70 | [:vhost]
71 | ]
72 | ]
73 | ]
74 | end
75 |
76 | newparam(:name) do
77 | desc 'resource name, either source@destination@vhost or arbitrary name with params'
78 |
79 | isnamevar
80 | end
81 |
82 | newproperty(:source) do
83 | desc 'source of binding'
84 |
85 | newvalues(%r{^\S+$})
86 | isnamevar
87 | end
88 |
89 | newproperty(:destination) do
90 | desc 'destination of binding'
91 |
92 | newvalues(%r{^\S+$})
93 | isnamevar
94 | end
95 |
96 | newproperty(:vhost) do
97 | desc 'vhost'
98 |
99 | newvalues(%r{^\S+$})
100 | defaultto('/')
101 | isnamevar
102 | end
103 |
104 | newproperty(:routing_key) do
105 | desc 'binding routing_key'
106 |
107 | newvalues(%r{^\S*$})
108 | isnamevar
109 | end
110 |
111 | newproperty(:destination_type) do
112 | desc 'binding destination_type'
113 | newvalues(%r{queue|exchange})
114 | defaultto('queue')
115 | end
116 |
117 | newproperty(:arguments) do
118 | desc 'binding arguments'
119 | defaultto({})
120 | validate do |value|
121 | resource.validate_argument(value)
122 | end
123 | end
124 |
125 | newparam(:user) do
126 | desc 'The user to use to connect to rabbitmq'
127 | defaultto('guest')
128 | newvalues(%r{^\S+$})
129 | end
130 |
131 | newparam(:password) do
132 | desc 'The password to use to connect to rabbitmq'
133 | defaultto('guest')
134 | newvalues(%r{\S+})
135 | end
136 |
137 | autorequire(:rabbitmq_vhost) do
138 | setup_autorequire('vhost')
139 | end
140 |
141 | autorequire(:rabbitmq_exchange) do
142 | setup_autorequire('exchange')
143 | end
144 |
145 | autorequire(:rabbitmq_queue) do
146 | setup_autorequire('queue')
147 | end
148 |
149 | autorequire(:rabbitmq_user) do
150 | [self[:user]]
151 | end
152 |
153 | autorequire(:rabbitmq_user_permissions) do
154 | [
155 | "#{self[:user]}@#{self[:source]}",
156 | "#{self[:user]}@#{self[:destination]}"
157 | ]
158 | end
159 |
160 | def setup_autorequire(type)
161 | destination_type = value(:destination_type)
162 | if type == 'exchange'
163 | rval = ["#{self[:source]}@#{self[:vhost]}"]
164 | rval.push("#{self[:destination]}@#{self[:vhost]}") if destination_type == type
165 | else
166 | rval = if destination_type == type
167 | ["#{self[:destination]}@#{self[:vhost]}"]
168 | else
169 | []
170 | end
171 | end
172 | rval
173 | end
174 |
175 | def validate_argument(argument)
176 | raise ArgumentError, 'Invalid argument' unless [Hash].include?(argument.class)
177 | end
178 |
179 | # Validate that we have both source and destination now that these are not
180 | # necessarily only coming from the resource title.
181 | validate do
182 | raise ArgumentError, '`source` must be defined' if !self[:source] && provider.source == :absent
183 |
184 | raise ArgumentError, '`destination` must be defined' if !self[:destination] && provider.destination == :absent
185 | end
186 | end
187 |
--------------------------------------------------------------------------------
/lib/puppet/type/rabbitmq_cluster.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | Puppet::Type.newtype(:rabbitmq_cluster) do
4 | desc <<~DESC
5 | Native type for managing rabbitmq cluster
6 |
7 | @example Configure a cluster, rabbit_cluster
8 | rabbitmq_cluster { 'rabbit_cluster':
9 | init_node => 'host1'
10 | }
11 |
12 | @example Optional parameter tags will set further rabbitmq tags like monitoring, policymaker, etc.
13 | To set the cluster name use cluster_name.
14 | rabbitmq_cluster { 'rabbit_cluster':
15 | init_node => 'host1',
16 | node_disc_type => 'ram',
17 | }
18 | DESC
19 |
20 | ensurable do
21 | desc 'Whether the resource should be present or absent'
22 | defaultto(:present)
23 | newvalue(:present) do
24 | provider.create
25 | end
26 | newvalue(:absent) do
27 | provider.destroy
28 | end
29 | end
30 |
31 | autorequire(:service) { 'rabbitmq-server' }
32 |
33 | newparam(:name, namevar: true) do
34 | desc 'The cluster name'
35 | end
36 |
37 | newparam(:init_node) do
38 | desc 'Name of which cluster node to join.'
39 | validate do |value|
40 | resource.validate_init_node(value)
41 | end
42 | end
43 |
44 | newparam(:local_node) do
45 | desc 'Name of the local node'
46 | defaultto(:undef)
47 | end
48 |
49 | newparam(:node_disc_type) do
50 | desc 'Storage type of node, default disc.'
51 | newvalues(%r{disc|ram})
52 | defaultto('disc')
53 | end
54 |
55 | def validate_init_node(value)
56 | raise ArgumentError, 'init_node must be defined' if value.empty?
57 | end
58 | end
59 |
--------------------------------------------------------------------------------
/lib/puppet/type/rabbitmq_erlang_cookie.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | Puppet::Type.newtype(:rabbitmq_erlang_cookie) do
4 | desc <<~DESC
5 | Type to manage the rabbitmq erlang cookie securely
6 |
7 | This is essentially a private type used by the rabbitmq::config class
8 | to manage the erlang cookie. It replaces the rabbitmq_erlang_cookie fact
9 | from earlier versions of this module. It manages the content of the cookie
10 | usually located at "${rabbitmq_home}/.erlang.cookie", which includes
11 | stopping the rabbitmq service and wiping out the database at
12 | "${rabbitmq_home}/mnesia" if the user agrees to it. We don't recommend using
13 | this type directly.
14 | DESC
15 |
16 | newparam(:path, namevar: true) do
17 | desc 'Path of the erlang cookie'
18 | end
19 |
20 | newproperty(:content) do
21 | desc 'Content of cookie'
22 | newvalues(%r{^\S+$})
23 |
24 | def change_to_s(_current, _desired)
25 | 'The rabbitmq erlang cookie was changed'
26 | end
27 |
28 | def is_to_s(_value)
29 | '[old content redacted]'
30 | end
31 |
32 | def should_to_s(_value)
33 | '[new content redacted]'
34 | end
35 | end
36 |
37 | newparam(:force) do
38 | desc 'Force parameter'
39 | defaultto(:false)
40 | newvalues(:true, :false)
41 | end
42 |
43 | newparam(:rabbitmq_user) do
44 | desc 'Rabbitmq User'
45 | defaultto('rabbitmq')
46 | end
47 |
48 | newparam(:rabbitmq_group) do
49 | desc 'Rabbitmq Group'
50 | defaultto('rabbitmq')
51 | end
52 |
53 | newparam(:rabbitmq_home) do
54 | desc 'Path to the rabbitmq home directory'
55 | defaultto('/var/lib/rabbitmq')
56 | end
57 |
58 | newparam(:service_name) do
59 | desc 'Name of the service'
60 | newvalues(%r{^\S+$})
61 | end
62 | end
63 |
--------------------------------------------------------------------------------
/lib/puppet/type/rabbitmq_exchange.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | Puppet::Type.newtype(:rabbitmq_exchange) do
4 | desc <<~DESC
5 | Native type for managing rabbitmq exchanges
6 |
7 | @example Create a rabbitmq_exchange
8 | rabbitmq_exchange { 'myexchange@myvhost':
9 | user => 'dan',
10 | password => 'bar',
11 | type => 'topic',
12 | ensure => present,
13 | internal => false,
14 | auto_delete => false,
15 | durable => true,
16 | arguments => {
17 | hash-header => 'message-distribution-hash'
18 | }
19 | }
20 | DESC
21 |
22 | ensurable do
23 | desc 'Whether the resource should be present or absent'
24 | defaultto(:present)
25 | newvalue(:present) do
26 | provider.create
27 | end
28 | newvalue(:absent) do
29 | provider.destroy
30 | end
31 | end
32 |
33 | newparam(:name, namevar: true) do
34 | desc 'Name of exchange'
35 | newvalues(%r{^\S*@\S+$})
36 | end
37 |
38 | newparam(:type) do
39 | desc 'Exchange type to be set *on creation*'
40 | newvalues(%r{^\S+$})
41 | end
42 |
43 | newparam(:durable) do
44 | desc 'Exchange durability to be set *on creation*'
45 | newvalues(%r{^\S+$})
46 | defaultto 'false'
47 | end
48 |
49 | newparam(:auto_delete) do
50 | desc 'Exchange auto delete option to be set *on creation*'
51 | newvalues(%r{^\S+$})
52 | defaultto 'false'
53 | end
54 |
55 | newparam(:internal) do
56 | desc 'Exchange internal option to be set *on creation*'
57 | newvalues(%r{^\S+$})
58 | defaultto 'false'
59 | end
60 |
61 | newparam(:arguments) do
62 | desc 'Exchange arguments example: {"hash-header": "message-distribution-hash"}'
63 | defaultto({})
64 | end
65 |
66 | newparam(:user) do
67 | desc 'The user to use to connect to rabbitmq'
68 | defaultto('guest')
69 | newvalues(%r{^\S+$})
70 | end
71 |
72 | newparam(:password) do
73 | desc 'The password to use to connect to rabbitmq'
74 | defaultto('guest')
75 | newvalues(%r{\S+})
76 | end
77 |
78 | validate do
79 | raise ArgumentError, "must set type when creating exchange for #{self[:name]} whose type is #{self[:type]}" if self[:ensure] == :present && self[:type].nil?
80 | end
81 |
82 | autorequire(:rabbitmq_vhost) do
83 | [self[:name].split('@')[1]]
84 | end
85 |
86 | autorequire(:rabbitmq_user) do
87 | [self[:user]]
88 | end
89 |
90 | autorequire(:rabbitmq_user_permissions) do
91 | ["#{self[:user]}@#{self[:name].split('@')[1]}"]
92 | end
93 | end
94 |
--------------------------------------------------------------------------------
/lib/puppet/type/rabbitmq_parameter.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | Puppet::Type.newtype(:rabbitmq_parameter) do
4 | desc <<~DESC
5 | Type for managing rabbitmq parameters
6 |
7 | @example Create some rabbitmq_parameter resources
8 | rabbitmq_parameter { 'documentumShovel@/':
9 | component_name => '',
10 | value => {
11 | 'src-uri' => 'amqp://',
12 | 'src-queue' => 'my-queue',
13 | 'dest-uri' => 'amqp://remote-server',
14 | 'dest-queue' => 'another-queue',
15 | },
16 | }
17 | rabbitmq_parameter { 'documentumFed@/':
18 | component_name => 'federation-upstream',
19 | value => {
20 | 'uri' => 'amqp://myserver',
21 | 'expires' => '360000',
22 | },
23 | }
24 | rabbitmq_parameter { 'documentumShovelNoMunging@/':
25 | component_name => '',
26 | value => {
27 | 'src-uri' => 'amqp://',
28 | 'src-exchange' => 'my-exchange',
29 | 'src-exchange-key' => '6',
30 | 'src-queue' => 'my-queue',
31 | 'dest-uri' => 'amqp://remote-server',
32 | 'dest-exchange' => 'another-exchange',
33 | },
34 | autoconvert => false,
35 | }
36 | DESC
37 |
38 | ensurable do
39 | desc 'Whether the resource should be present or absent'
40 | defaultto(:present)
41 | newvalue(:present) do
42 | provider.create
43 | end
44 | newvalue(:absent) do
45 | provider.destroy
46 | end
47 | end
48 |
49 | autorequire(:service) { 'rabbitmq-server' }
50 |
51 | validate do
52 | raise('component_name parameter is required.') if self[:ensure] == :present && provider.component_name.nil?
53 | raise('value parameter is required.') if self[:ensure] == :present && provider.value.nil?
54 | end
55 |
56 | newparam(:name, namevar: true) do
57 | desc 'combination of name@vhost to set parameter for'
58 | newvalues(%r{^\S+@\S+$})
59 | end
60 |
61 | newproperty(:component_name) do
62 | desc 'The component_name to use when setting parameter, eg: shovel or federation'
63 | validate do |value|
64 | resource.validate_component_name(value)
65 | end
66 | end
67 |
68 | newparam(:autoconvert) do
69 | desc 'whether numeric strings from `value` should be converted to int automatically'
70 | newvalues(:true, :false)
71 | defaultto(:true)
72 | end
73 |
74 | newproperty(:value) do
75 | desc 'A hash of values to use with the component name you are setting'
76 | validate do |value|
77 | resource.validate_value(value)
78 | end
79 | munge do |value|
80 | resource.munge_value(value)
81 | end
82 | end
83 |
84 | autorequire(:rabbitmq_vhost) do
85 | [self[:name].split('@')[1]]
86 | end
87 |
88 | def set_parameters(hash) # rubocop:disable Naming/AccessorMethodName
89 | # Hack to ensure :autoconvert is initialized before :value
90 | self[:autoconvert] = hash[:autoconvert] if hash.key?(:autoconvert)
91 | super
92 | end
93 |
94 | def validate_component_name(value)
95 | raise ArgumentError, 'component_name must be defined' if value.empty?
96 | end
97 |
98 | def validate_value(value)
99 | raise ArgumentError, 'Invalid value' unless [Hash].include?(value.class)
100 |
101 | value.each do |_k, v|
102 | raise ArgumentError, 'Invalid value' unless [String, TrueClass, FalseClass, Array].include?(v.class)
103 | end
104 | end
105 |
106 | def munge_value(value)
107 | return value if value(:autoconvert) == :false
108 |
109 | value.transform_values do |v|
110 | if v.is_a?(String) && v.match?(%r{\A[-+]?[0-9]+\z})
111 | v.to_i
112 | else
113 | v
114 | end
115 | end
116 | end
117 | end
118 |
--------------------------------------------------------------------------------
/lib/puppet/type/rabbitmq_plugin.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | Puppet::Type.newtype(:rabbitmq_plugin) do
4 | desc <<~DESC
5 | manages rabbitmq plugins
6 |
7 | @example query all currently enabled plugins
8 | $ puppet resource rabbitmq_plugin
9 |
10 | @example Ensure a rabbitmq_plugin resource
11 | rabbitmq_plugin {'rabbitmq_stomp':
12 | ensure => present,
13 | }
14 |
15 | @example Ensure a rabbitmq_plugin offline resource (with RabbitMQ version >=3.4.0)
16 | rabbitmq_plugin {'rabbitmq_stomp':
17 | ensure => present,
18 | mode => 'offline',
19 | }
20 | DESC
21 |
22 | ensurable do
23 | desc 'Whether the resource should be present or absent'
24 | defaultto(:present)
25 | newvalue(:present) do
26 | provider.create
27 | end
28 | newvalue(:absent) do
29 | provider.destroy
30 | end
31 | end
32 |
33 | newparam(:name, namevar: true) do
34 | desc 'The name of the plugin to enable'
35 | newvalues(%r{^\S+$})
36 | end
37 |
38 | newparam(:mode) do
39 | desc 'Define how the plugin should be enabled regarding node status.'
40 | newvalues(:online, :offline, :best)
41 | defaultto(:best)
42 | end
43 |
44 | newparam(:umask) do
45 | desc 'Sets the octal umask to be used while creating this resource'
46 | defaultto '0022'
47 | munge do |value|
48 | raise Puppet::Error, "The umask specification is invalid: #{value.inspect}" unless value =~ %r{^0?[0-7]{1,3}$}
49 |
50 | return value.to_i(8)
51 | end
52 | end
53 | end
54 |
--------------------------------------------------------------------------------
/lib/puppet/type/rabbitmq_policy.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | # See below; these are variables that we want to auto-convert to integer
4 | # values
5 | CONVERT_TO_INT_VARS = %w[
6 | consumer-timeout
7 | delivery-limit
8 | expires
9 | ha-sync-batch-size
10 | initial-cluster-size
11 | max-length
12 | max-length-bytes
13 | message-ttl
14 | queue-version
15 | shards-per-node
16 | target-group-size
17 | ].freeze
18 |
19 | Puppet::Type.newtype(:rabbitmq_policy) do
20 | desc <<~DESC
21 | Type for managing rabbitmq policies
22 |
23 | @example Create a rabbitmq_policy
24 | rabbitmq_policy { 'ha-all@myvhost':
25 | pattern => '.*',
26 | priority => 0,
27 | applyto => 'all',
28 | definition => {
29 | 'ha-mode' => 'all',
30 | 'ha-sync-mode' => 'automatic',
31 | },
32 | }
33 | DESC
34 |
35 | ensurable do
36 | desc 'Whether the resource should be present or absent'
37 | defaultto(:present)
38 | newvalue(:present) do
39 | provider.create
40 | end
41 | newvalue(:absent) do
42 | provider.destroy
43 | end
44 | end
45 |
46 | autorequire(:service) { 'rabbitmq-server' }
47 |
48 | validate do
49 | raise('pattern parameter is required.') if self[:ensure] == :present && self[:pattern].nil?
50 | raise('definition parameter is required.') if self[:ensure] == :present && self[:definition].nil?
51 | end
52 |
53 | newparam(:name, namevar: true) do
54 | desc 'combination of policy@vhost to create policy for'
55 | newvalues(%r{^\S+@\S+$})
56 | end
57 |
58 | newproperty(:pattern) do
59 | desc 'policy pattern'
60 | validate do |value|
61 | resource.validate_pattern(value)
62 | end
63 | end
64 |
65 | newproperty(:applyto) do
66 | desc 'policy apply to'
67 | newvalue(:all)
68 | newvalue(:classic_queues)
69 | newvalue(:exchanges)
70 | newvalue(:queues)
71 | newvalue(:quorum_queues)
72 | newvalue(:streams)
73 | defaultto :all
74 | end
75 |
76 | newproperty(:definition) do
77 | desc 'policy definition'
78 | validate do |value|
79 | resource.validate_definition(value)
80 | end
81 | munge do |value|
82 | resource.munge_definition(value)
83 | end
84 | end
85 |
86 | newproperty(:priority) do
87 | desc 'policy priority'
88 | newvalues(%r{^\d+$})
89 | defaultto 0
90 | end
91 |
92 | autorequire(:rabbitmq_vhost) do
93 | [self[:name].split('@')[1]]
94 | end
95 |
96 | def validate_pattern(value)
97 | Regexp.new(value)
98 | rescue RegexpError
99 | raise ArgumentError, "Invalid regexp #{value}"
100 | end
101 |
102 | def validate_definition(definition)
103 | raise ArgumentError, 'Invalid definition' unless [Hash].include?(definition.class)
104 |
105 | definition.each do |k, v|
106 | if k == 'ha-params' && definition['ha-mode'] == 'nodes'
107 | raise ArgumentError, "Invalid definition, value #{v} for key #{k} is not an array" unless [Array].include?(v.class)
108 | else
109 | raise ArgumentError, "Invalid definition, value #{v} is not a string" unless [String].include?(v.class)
110 | end
111 | end
112 | if definition['ha-mode'] == 'exactly'
113 | ha_params = definition['ha-params']
114 | raise ArgumentError, "Invalid ha-params '#{ha_params}' for ha-mode 'exactly'" unless ha_params.to_i.to_s == ha_params
115 | end
116 |
117 | # Since this pattern is repeated, use a constant to track all the types
118 | # where we need to convert a string value to an unquoted integer explicitly
119 | definition.each do |k, v|
120 | raise ArgumentError, "Invalid #{k} value '#{v}'" if CONVERT_TO_INT_VARS.include?(k) && v.to_i.to_s != v
121 | end
122 | end
123 |
124 | def munge_definition(definition)
125 | definition['ha-params'] = definition['ha-params'].to_i if definition['ha-mode'] == 'exactly'
126 |
127 | # Again, use a list of types to convert vs. hard-coding each one
128 | definition.each do |k, v|
129 | definition[k] = v.to_i if CONVERT_TO_INT_VARS.include? k
130 | end
131 |
132 | definition
133 | end
134 | end
135 |
--------------------------------------------------------------------------------
/lib/puppet/type/rabbitmq_queue.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | Puppet::Type.newtype(:rabbitmq_queue) do
4 | desc <<~DESC
5 | Native type for managing rabbitmq queue
6 |
7 | @example Create a rabbitmq_queue
8 | rabbitmq_queue { 'myqueue@myvhost':
9 | ensure => present,
10 | user => 'dan',
11 | password => 'bar',
12 | durable => true,
13 | auto_delete => false,
14 | arguments => {
15 | x-message-ttl => 123,
16 | x-dead-letter-exchange => 'other'
17 | },
18 | }
19 | DESC
20 |
21 | ensurable do
22 | desc 'Whether the resource should be present or absent'
23 | defaultto(:present)
24 | newvalue(:present) do
25 | provider.create
26 | end
27 | newvalue(:absent) do
28 | provider.destroy
29 | end
30 | end
31 |
32 | newparam(:name, namevar: true) do
33 | desc 'Name of queue'
34 | newvalues(%r{^\S*@\S+$})
35 | end
36 |
37 | newparam(:durable) do
38 | desc 'Queue is durable'
39 | newvalues(%r{true|false})
40 | defaultto('true')
41 | end
42 |
43 | newparam(:auto_delete) do
44 | desc 'Queue will be auto deleted'
45 | newvalues(%r{true|false})
46 | defaultto('false')
47 | end
48 |
49 | newparam(:arguments) do
50 | desc 'Queue arguments example: {x-message-ttl => 60, x-expires => 10}'
51 | defaultto({})
52 | validate do |value|
53 | resource.validate_argument(value)
54 | end
55 | end
56 |
57 | newparam(:user) do
58 | desc 'The user to use to connect to rabbitmq'
59 | defaultto('guest')
60 | newvalues(%r{^\S+$})
61 | end
62 |
63 | newparam(:password) do
64 | desc 'The password to use to connect to rabbitmq'
65 | defaultto('guest')
66 | newvalues(%r{\S+})
67 | end
68 |
69 | autorequire(:rabbitmq_vhost) do
70 | [self[:name].split('@')[1]]
71 | end
72 |
73 | autorequire(:rabbitmq_user) do
74 | [self[:user]]
75 | end
76 |
77 | autorequire(:rabbitmq_user_permissions) do
78 | ["#{self[:user]}@#{self[:name].split('@')[1]}"]
79 | end
80 |
81 | def validate_argument(argument)
82 | raise ArgumentError, 'Invalid argument' unless [Hash].include?(argument.class)
83 | end
84 | end
85 |
--------------------------------------------------------------------------------
/lib/puppet/type/rabbitmq_user.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | Puppet::Type.newtype(:rabbitmq_user) do
4 | desc <<~DESC
5 | Native type for managing rabbitmq users
6 |
7 | @example query all current users
8 | $ puppet resource rabbitmq_user
9 |
10 | @example Configure a user, dan
11 | rabbitmq_user { 'dan':
12 | admin => true,
13 | password => 'bar',
14 | }
15 |
16 | @example Optional parameter tags will set further rabbitmq tags like monitoring, policymaker, etc.
17 | To set the administrator tag use admin-flag.
18 | rabbitmq_user { 'dan':
19 | admin => true,
20 | password => 'bar',
21 | tags => ['monitoring', 'tag1'],
22 | }
23 | DESC
24 |
25 | ensurable do
26 | desc 'Whether the resource should be present or absent'
27 | defaultto(:present)
28 | newvalue(:present) do
29 | provider.create
30 | end
31 | newvalue(:absent) do
32 | provider.destroy
33 | end
34 | end
35 |
36 | autorequire(:service) { 'rabbitmq-server' }
37 |
38 | newparam(:name, namevar: true) do
39 | desc 'Name of user'
40 | newvalues(%r{^\S+$})
41 | end
42 |
43 | newproperty(:password) do
44 | desc 'User password to be set *on creation* and validated each run'
45 | def insync?(_is)
46 | provider.check_password(should)
47 | end
48 |
49 | def change_to_s(_current, _desired)
50 | 'password has been changed'
51 | end
52 |
53 | def is_to_s(_value)
54 | '[old password redacted]'
55 | end
56 |
57 | def should_to_s(_value)
58 | '[new password redacted]'
59 | end
60 | end
61 |
62 | newproperty(:admin) do
63 | desc 'whether or not user should be an admin'
64 | newvalues(%r{true|false})
65 | munge do |value|
66 | # converting to_s in case its a boolean
67 | value.to_s.to_sym
68 | end
69 | defaultto :false
70 | end
71 |
72 | newproperty(:tags, array_matching: :all) do
73 | desc 'additional tags for the user'
74 | validate do |value|
75 | raise ArgumentError, "Invalid tag: #{value.inspect}" unless value =~ %r{^\S+$}
76 |
77 | raise ArgumentError, 'must use admin property instead of administrator tag' if value == 'administrator'
78 | end
79 | defaultto []
80 |
81 | def insync?(is)
82 | is.sort == should.sort
83 | end
84 |
85 | def should_to_s(value)
86 | Array(value)
87 | end
88 | end
89 | end
90 |
--------------------------------------------------------------------------------
/lib/puppet/type/rabbitmq_user_permissions.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | Puppet::Type.newtype(:rabbitmq_user_permissions) do
4 | desc <<~DESC
5 | Type for managing rabbitmq user permissions
6 |
7 | @example Define some rabbitmq_user_permissions
8 | rabbitmq_user_permissions { 'dan@myvhost':
9 | configure_permission => '.*',
10 | read_permission => '.*',
11 | write_permission => '.*',
12 | }
13 | DESC
14 |
15 | ensurable do
16 | desc 'Whether the resource should be present or absent'
17 | defaultto(:present)
18 | newvalue(:present) do
19 | provider.create
20 | end
21 | newvalue(:absent) do
22 | provider.destroy
23 | end
24 | end
25 |
26 | autorequire(:service) { 'rabbitmq-server' }
27 |
28 | newparam(:name, namevar: true) do
29 | desc 'combination of user@vhost to grant privileges to'
30 | newvalues(%r{^\S+@\S+$})
31 | end
32 |
33 | newproperty(:configure_permission) do
34 | desc 'regexp representing configuration permissions'
35 | validate do |value|
36 | resource.validate_permissions(value)
37 | end
38 | end
39 |
40 | newproperty(:read_permission) do
41 | desc 'regexp representing read permissions'
42 | validate do |value|
43 | resource.validate_permissions(value)
44 | end
45 | end
46 |
47 | newproperty(:write_permission) do
48 | desc 'regexp representing write permissions'
49 | validate do |value|
50 | resource.validate_permissions(value)
51 | end
52 | end
53 |
54 | autorequire(:rabbitmq_vhost) do
55 | [self[:name].split('@')[1]]
56 | end
57 |
58 | autorequire(:rabbitmq_user) do
59 | [self[:name].split('@')[0]]
60 | end
61 |
62 | def validate_permissions(value)
63 | Regexp.new(value)
64 | rescue RegexpError
65 | raise ArgumentError, "Invalid regexp #{value}"
66 | end
67 | end
68 |
--------------------------------------------------------------------------------
/lib/puppet/type/rabbitmq_vhost.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | Puppet::Type.newtype(:rabbitmq_vhost) do
4 | desc <<~DESC
5 | Native type for managing rabbitmq vhosts
6 |
7 | @example query all current vhosts
8 | $ puppet resource rabbitmq_vhost`
9 |
10 | @example Create a rabbitmq_vhost
11 | rabbitmq_vhost { 'myvhost':
12 | ensure => present,
13 | description => 'myvhost description',
14 | tags => ['tag1', 'tag2'],
15 | default_queue_type => 'quorum',
16 | }
17 | DESC
18 |
19 | ensurable do
20 | desc 'Whether the resource should be present or absent'
21 | defaultto(:present)
22 | newvalue(:present) do
23 | provider.create
24 | end
25 | newvalue(:absent) do
26 | provider.destroy
27 | end
28 | end
29 |
30 | autorequire(:service) { 'rabbitmq-server' }
31 |
32 | newparam(:name, namevar: true) do
33 | desc 'The name of the vhost to add'
34 | newvalues(%r{^\S+$})
35 | end
36 |
37 | newproperty(:description) do
38 | desc 'A description of the vhost'
39 | end
40 |
41 | newproperty(:default_queue_type) do
42 | desc 'The default queue type for queues in this vhost'
43 | newvalues(:classic, :quorum, :stream)
44 | munge(&:to_s)
45 | end
46 |
47 | newproperty(:tags, array_matching: :all) do
48 | desc 'additional tags for the vhost'
49 | validate do |value|
50 | raise ArgumentError, "Invalid tag: #{value.inspect}" unless value =~ %r{^\S+$}
51 | end
52 | defaultto []
53 | end
54 | end
55 |
--------------------------------------------------------------------------------
/locales/config.yaml:
--------------------------------------------------------------------------------
1 | ---
2 | # This is the project-specific configuration file for setting up
3 | # fast_gettext for your project.
4 | gettext:
5 | # This is used for the name of the .pot and .po files; they will be
6 | # called .pot?
7 | project_name: puppetlabs-rabbitmq
8 | # This is used in comments in the .pot and .po files to indicate what
9 | # project the files belong to and should bea little more desctiptive than
10 | #
11 | package_name: puppetlabs-rabbitmq
12 | # The locale that the default messages in the .pot file are in
13 | default_locale: en
14 | # The email used for sending bug reports.
15 | bugs_address: docs@puppet.com
16 | # The holder of the copyright.
17 | copyright_holder: Puppet, Inc.
18 | # This determines which comments in code should be eligible for translation.
19 | # Any comments that start with this string will be externalized. (Leave
20 | # empty to include all.)
21 | comments_tag: TRANSLATOR
22 | # Patterns for +Dir.glob+ used to find all files that might contain
23 | # translatable content, relative to the project root directory
24 | source_files:
25 |
26 |
--------------------------------------------------------------------------------
/manifests/install.pp:
--------------------------------------------------------------------------------
1 | # Ensures that rabbitmq-server exists
2 | #
3 | # @api private
4 | class rabbitmq::install {
5 | $package_ensure = $rabbitmq::package_ensure
6 | $package_name = $rabbitmq::package_name
7 | $rabbitmq_group = $rabbitmq::rabbitmq_group
8 |
9 | package { $package_name:
10 | ensure => $package_ensure,
11 | notify => Class['rabbitmq::service'],
12 | }
13 |
14 | if $rabbitmq::environment_variables['MNESIA_BASE'] {
15 | file { $rabbitmq::environment_variables['MNESIA_BASE']:
16 | ensure => 'directory',
17 | owner => 'root',
18 | group => $rabbitmq_group,
19 | mode => '0775',
20 | require => Package[$package_name],
21 | }
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/manifests/install/rabbitmqadmin.pp:
--------------------------------------------------------------------------------
1 | # Install rabbitmq admin
2 | #
3 | # @api private
4 | class rabbitmq::install::rabbitmqadmin {
5 | if $rabbitmq::rabbitmqadmin_package {
6 | package { 'rabbitmqadmin':
7 | ensure => 'present',
8 | name => $rabbitmq::rabbitmqadmin_package,
9 | }
10 | } else {
11 | $python_package = $rabbitmq::python_package
12 | # Some systems (e.g., Ubuntu 16.04) don't ship Python 2 by default
13 | if $rabbitmq::manage_python {
14 | stdlib::ensure_packages([$python_package])
15 | $rabbitmqadmin_require = [Archive['rabbitmqadmin'], Package[$python_package]]
16 | } else {
17 | $rabbitmqadmin_require = Archive['rabbitmqadmin']
18 | }
19 |
20 | if($rabbitmq::ssl and $rabbitmq::management_ssl) {
21 | $management_port = $rabbitmq::ssl_management_port
22 | $protocol = 'https'
23 | } else {
24 | $management_port = $rabbitmq::management_port
25 | $protocol = 'http'
26 | }
27 |
28 | $default_user = $rabbitmq::default_user
29 | $default_pass = $rabbitmq::default_pass
30 | $archive_options = $rabbitmq::archive_options
31 |
32 | # This should be consistent with rabbitmq::config
33 | if $rabbitmq::management_ip_address {
34 | $management_ip_address = $rabbitmq::management_ip_address
35 | } else {
36 | $management_ip_address = $rabbitmq::node_ip_address
37 | }
38 |
39 | if !($management_ip_address) {
40 | # Pull from localhost if we don't have an explicit bind address
41 | $sanitized_ip = '127.0.0.1'
42 | } elsif $management_ip_address =~ Stdlib::IP::Address::V6::Nosubnet {
43 | $sanitized_ip = join(enclose_ipv6(any2array($management_ip_address)), ',')
44 | } else {
45 | $sanitized_ip = $management_ip_address
46 | }
47 |
48 | if !($rabbitmq::use_config_file_for_plugins) {
49 | $rabbitmqadmin_archive_require = [
50 | Class['rabbitmq::service'],
51 | Rabbitmq_plugin['rabbitmq_management'],
52 | Exec['remove_old_rabbitmqadmin_on_upgrade']
53 | ]
54 | } else {
55 | $rabbitmqadmin_archive_require = [
56 | Class['rabbitmq::service'],
57 | File['enabled_plugins'],
58 | Exec['remove_old_rabbitmqadmin_on_upgrade']
59 | ]
60 | }
61 |
62 | Exec { 'remove_old_rabbitmqadmin_on_upgrade':
63 | path => ['/bin','/usr/bin','/sbin','/usr/sbin'],
64 | command => "rm ${rabbitmq::rabbitmq_home}/rabbitmqadmin",
65 | onlyif => ["test -f ${rabbitmq::rabbitmq_home}/rabbitmqadmin"],
66 | refreshonly => true,
67 | }
68 |
69 | archive { 'rabbitmqadmin':
70 | path => "${rabbitmq::rabbitmq_home}/rabbitmqadmin",
71 | source => "${protocol}://${sanitized_ip}:${management_port}/cli/rabbitmqadmin",
72 | username => $default_user,
73 | password => $default_pass,
74 | allow_insecure => true,
75 | download_options => $archive_options,
76 | cleanup => false,
77 | require => $rabbitmqadmin_archive_require,
78 | }
79 |
80 | file { '/usr/local/bin/rabbitmqadmin':
81 | owner => 'root',
82 | group => '0',
83 | source => "${rabbitmq::rabbitmq_home}/rabbitmqadmin",
84 | mode => '0755',
85 | require => $rabbitmqadmin_require,
86 | }
87 | }
88 | }
89 |
--------------------------------------------------------------------------------
/manifests/management.pp:
--------------------------------------------------------------------------------
1 | # Manage presence / absence of user resource for guest management user.
2 | #
3 | # @api private
4 | class rabbitmq::management {
5 | $delete_guest_user = $rabbitmq::delete_guest_user
6 |
7 | if $delete_guest_user {
8 | rabbitmq_user { 'guest':
9 | ensure => absent,
10 | provider => 'rabbitmqctl',
11 | }
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/manifests/repo/apt.pp:
--------------------------------------------------------------------------------
1 | # requires
2 | # puppetlabs-apt
3 | # puppetlabs-stdlib
4 | #
5 | # @api private
6 | #
7 | # @param location
8 | # @param repos
9 | # @param include_src
10 | # @param key
11 | # @param key_source
12 | # @param key_content
13 | # @param architecture
14 | #
15 | class rabbitmq::repo::apt (
16 | String[1] $location = 'https://packagecloud.io/rabbitmq/rabbitmq-server',
17 | String[1] $repos = 'main',
18 | Boolean $include_src = false,
19 | String[1] $key = '8C695B0219AFDEB04A058ED8F4E789204D206F89',
20 | String[1] $key_source = $rabbitmq::package_gpg_key,
21 | Optional[String[1]] $key_content = $rabbitmq::key_content,
22 | Optional[String[1]] $architecture = undef,
23 | ) {
24 | $osname = downcase($facts['os']['name'])
25 | $pin = $rabbitmq::package_apt_pin
26 |
27 | apt::source { 'rabbitmq':
28 | ensure => present,
29 | location => "${location}/${osname}",
30 | repos => $repos,
31 | include => { 'src' => $include_src },
32 | key => {
33 | 'id' => $key,
34 | 'source' => $key_source,
35 | 'content' => $key_content,
36 | },
37 | architecture => $architecture,
38 | }
39 |
40 | if $pin {
41 | apt::pin { 'rabbitmq':
42 | packages => '*',
43 | priority => $pin,
44 | origin => inline_template('<%= require \'uri\'; URI(@location).host %>'),
45 | }
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/manifests/repo/rhel.pp:
--------------------------------------------------------------------------------
1 | # Makes sure that the Packagecloud repo is installed
2 | #
3 | # @api private
4 | #
5 | # @param location
6 | # @param repo_key_source
7 | # @param package_key_source
8 | #
9 | class rabbitmq::repo::rhel (
10 | String[1] $location = "https://packagecloud.io/rabbitmq/rabbitmq-server/el/${facts['os'][release][major]}/\$basearch",
11 | String[1] $repo_key_source = $rabbitmq::repo_gpg_key,
12 | String[1] $package_key_source = $rabbitmq::package_gpg_key,
13 | ) {
14 | # Import package key from rabbitmq to be able to
15 | # sign the package and the repo.
16 | # rabbitmq key is gpg-pubkey-6026dfca-573adfde
17 | exec { "rpm --import ${package_key_source}":
18 | path => ['/bin','/usr/bin','/sbin','/usr/sbin'],
19 | unless => 'rpm -q gpg-pubkey-6026dfca-573adfde 2>/dev/null',
20 | before => YumRepo['rabbitmq'],
21 | }
22 |
23 | yumrepo { 'rabbitmq':
24 | ensure => present,
25 | name => 'rabbitmq_rabbitmq-server',
26 | baseurl => $location,
27 | gpgkey => $repo_key_source,
28 | enabled => 1,
29 | gpgcheck => 1,
30 | repo_gpgcheck => 1,
31 | }
32 |
33 | # This may still be needed to prevent warnings
34 | # packagecloud key is gpg-pubkey-4d206f89-5bbb8d59
35 | exec { "rpm --import ${repo_key_source}":
36 | path => ['/bin','/usr/bin','/sbin','/usr/sbin'],
37 | unless => 'rpm -q gpg-pubkey-4d206f89-5bbb8d59 2>/dev/null',
38 | require => YumRepo['rabbitmq'],
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/manifests/service.pp:
--------------------------------------------------------------------------------
1 | # This class manages the rabbitmq server service itself.
2 | #
3 | # @api private
4 | #
5 | # @param service_ensure
6 | # @param service_manage
7 | # @param service_name
8 | #
9 | class rabbitmq::service (
10 | Enum['running', 'stopped'] $service_ensure = $rabbitmq::service_ensure,
11 | Boolean $service_manage = $rabbitmq::service_manage,
12 | String[1] $service_name = $rabbitmq::service_name,
13 | ) inherits rabbitmq {
14 | if ($service_manage) {
15 | if $service_ensure == 'running' {
16 | $ensure_real = 'running'
17 | $enable_real = true
18 | } else {
19 | $ensure_real = 'stopped'
20 | $enable_real = false
21 | }
22 |
23 | service { 'rabbitmq-server':
24 | ensure => $ensure_real,
25 | enable => $enable_real,
26 | hasstatus => true,
27 | hasrestart => true,
28 | name => $service_name,
29 | }
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/metadata.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "puppet-rabbitmq",
3 | "version": "14.4.0",
4 | "author": "Vox Pupuli",
5 | "summary": "Installs, configures, and manages RabbitMQ.",
6 | "license": "Apache-2.0",
7 | "source": "https://github.com/voxpupuli/puppet-rabbitmq",
8 | "project_page": "https://github.com/voxpupuli/puppet-rabbitmq",
9 | "issues_url": "https://github.com/voxpupuli/puppet-rabbitmq/issues",
10 | "operatingsystem_support": [
11 | {
12 | "operatingsystem": "RedHat",
13 | "operatingsystemrelease": [
14 | "9"
15 | ]
16 | },
17 | {
18 | "operatingsystem": "CentOS",
19 | "operatingsystemrelease": [
20 | "9"
21 | ]
22 | },
23 | {
24 | "operatingsystem": "Debian",
25 | "operatingsystemrelease": [
26 | "11"
27 | ]
28 | },
29 | {
30 | "operatingsystem": "Ubuntu",
31 | "operatingsystemrelease": [
32 | "20.04",
33 | "22.04"
34 | ]
35 | },
36 | {
37 | "operatingsystem": "SLES",
38 | "operatingsystemrelease": [
39 | "11"
40 | ]
41 | },
42 | {
43 | "operatingsystem": "FreeBSD",
44 | "operatingsystemrelease": [
45 | "13",
46 | "14"
47 | ]
48 | },
49 | {
50 | "operatingsystem": "OpenBSD"
51 | }
52 | ],
53 | "requirements": [
54 | {
55 | "name": "puppet",
56 | "version_requirement": ">= 7.0.0 < 9.0.0"
57 | },
58 | {
59 | "name": "openvox",
60 | "version_requirement": ">= 7.0.0 < 9.0.0"
61 | }
62 | ],
63 | "dependencies": [
64 | {
65 | "name": "puppetlabs/stdlib",
66 | "version_requirement": ">= 4.25.0 < 10.0.0"
67 | },
68 | {
69 | "name": "puppet/archive",
70 | "version_requirement": ">= 2.0.0 < 8.0.0"
71 | },
72 | {
73 | "name": "puppet/systemd",
74 | "version_requirement": ">= 6.0.0 < 9.0.0"
75 | }
76 | ],
77 | "tags": [
78 | "rabbitmq",
79 | "ampq",
80 | "messaging",
81 | "stomp",
82 | "queue"
83 | ]
84 | }
85 |
--------------------------------------------------------------------------------
/spec/README.markdown:
--------------------------------------------------------------------------------
1 | Specs
2 | =====
3 |
4 | The Puppet project uses RSpec for testing.
5 |
6 | For more information on RSpec, see http://rspec.info/
7 |
8 |
--------------------------------------------------------------------------------
/spec/acceptance/class_spec.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | require 'spec_helper_acceptance'
4 |
5 | describe 'rabbitmq class:' do
6 | case fact('os.family')
7 | when 'RedHat', 'SUSE', 'Debian'
8 | package_name = 'rabbitmq-server'
9 | service_name = 'rabbitmq-server'
10 | when 'Archlinux'
11 | package_name = 'rabbitmq'
12 | service_name = 'rabbitmq'
13 | end
14 |
15 | context 'default class inclusion' do
16 | let(:pp) do
17 | <<-EOS
18 | include rabbitmq
19 | EOS
20 | end
21 |
22 | it_behaves_like 'an idempotent resource'
23 |
24 | describe package(package_name) do
25 | it { is_expected.to be_installed }
26 | end
27 |
28 | describe service(service_name) do
29 | it { is_expected.to be_enabled }
30 | it { is_expected.to be_running }
31 | end
32 |
33 | describe file('/etc/rabbitmq') do
34 | it { is_expected.to be_directory }
35 | it { is_expected.to be_owned_by 'rabbitmq' }
36 | it { is_expected.to be_grouped_into 'rabbitmq' }
37 | end
38 |
39 | describe file('/etc/rabbitmq/ssl') do
40 | it { is_expected.to be_directory }
41 | it { is_expected.to be_owned_by 'rabbitmq' }
42 | it { is_expected.to be_grouped_into 'rabbitmq' }
43 | it { is_expected.not_to be_readable.by('others') }
44 | end
45 | end
46 |
47 | context 'disable and stop service' do
48 | let(:pp) do
49 | <<-EOS
50 | class { 'rabbitmq':
51 | service_ensure => 'stopped',
52 | }
53 | EOS
54 | end
55 |
56 | it_behaves_like 'an idempotent resource'
57 |
58 | describe service(service_name) do
59 | it { is_expected.not_to be_enabled }
60 | it { is_expected.not_to be_running }
61 | end
62 | end
63 |
64 | context 'service is unmanaged' do
65 | it 'runs successfully' do
66 | pp_pre = <<-EOS
67 | include rabbitmq
68 | EOS
69 |
70 | pp = <<-EOS
71 | class { 'rabbitmq':
72 | service_manage => false,
73 | service_ensure => 'stopped',
74 | }
75 | EOS
76 |
77 | apply_manifest(pp_pre, catch_failures: true)
78 | apply_manifest(pp, catch_failures: true)
79 | end
80 |
81 | describe service(service_name) do
82 | it { is_expected.to be_enabled }
83 | it { is_expected.to be_running }
84 | end
85 | end
86 |
87 | context 'binding on all interfaces' do
88 | let(:pp) do
89 | <<-EOS
90 | class { 'rabbitmq':
91 | service_manage => true,
92 | port => 5672,
93 | admin_enable => true,
94 | node_ip_address => '0.0.0.0'
95 | }
96 | EOS
97 | end
98 |
99 | it_behaves_like 'an idempotent resource'
100 |
101 | describe service(service_name) do
102 | it { is_expected.to be_running }
103 | end
104 |
105 | describe port(5672), :port5672 do
106 | it { is_expected.to be_listening.on('0.0.0.0').with('tcp') }
107 | end
108 |
109 | describe port(15_672) do
110 | it { is_expected.to be_listening.on('0.0.0.0').with('tcp') }
111 | end
112 |
113 | describe port(25_672) do
114 | xit 'Is on 55672 instead on older rmq versions' do
115 | is_expected.to be_listening.on('0.0.0.0').with('tcp')
116 | end
117 | end
118 | end
119 |
120 | context 'binding to localhost only' do
121 | let(:pp) do
122 | <<-EOS
123 | class { 'rabbitmq':
124 | service_manage => true,
125 | port => 5672,
126 | admin_enable => true,
127 | node_ip_address => '127.0.0.1'
128 | }
129 | EOS
130 | end
131 |
132 | it_behaves_like 'an idempotent resource'
133 |
134 | describe service(service_name) do
135 | it { is_expected.to be_running }
136 | end
137 |
138 | describe port(5672), :port5671 do
139 | it { is_expected.to be_listening.on('127.0.0.1').with('tcp') }
140 | end
141 |
142 | describe port(15_672) do
143 | it { is_expected.to be_listening.on('127.0.0.1').with('tcp') }
144 | end
145 |
146 | # This listens on all interfaces regardless of these settings
147 |
148 | describe port(25_672) do
149 | xit 'Is on 55672 instead on older rmq versions' do
150 | is_expected.to be_listening.on('0.0.0.0').with('tcp')
151 | end
152 | end
153 | end
154 |
155 | context 'ssl enabled' do
156 | let(:pp) do
157 | <<-EOS
158 | class { 'rabbitmq':
159 | service_manage => true,
160 | admin_enable => true,
161 | node_ip_address => '0.0.0.0',
162 | ssl_interface => '0.0.0.0',
163 | ssl => true,
164 | ssl_cacert => '/tmp/cacert.crt',
165 | ssl_cert => '/tmp/rabbitmq.crt',
166 | ssl_key => '/tmp/rabbitmq.key',
167 | }
168 | EOS
169 | end
170 |
171 | it_behaves_like 'an idempotent resource'
172 |
173 | describe service(service_name) do
174 | it { is_expected.to be_running }
175 | end
176 |
177 | describe port(5671), :port5671 do
178 | it { is_expected.to be_listening.on('0.0.0.0').with('tcp') }
179 | end
180 |
181 | describe port(15_671) do
182 | it { is_expected.to be_listening.on('0.0.0.0').with('tcp') }
183 | end
184 | end
185 |
186 | context 'different management_ip_address and node_ip_address' do
187 | let(:pp) do
188 | <<-EOS
189 | class { 'rabbitmq':
190 | service_manage => true,
191 | port => 5672,
192 | admin_enable => true,
193 | node_ip_address => '0.0.0.0',
194 | management_ip_address => '127.0.0.1'
195 | }
196 | EOS
197 | end
198 |
199 | it_behaves_like 'an idempotent resource'
200 |
201 | describe service(service_name) do
202 | it { is_expected.to be_running }
203 | end
204 |
205 | describe port(5672), :port5672 do
206 | it { is_expected.to be_listening.on('0.0.0.0').with('tcp') }
207 | end
208 |
209 | describe port(15_672) do
210 | it { is_expected.to be_listening.on('127.0.0.1').with('tcp') }
211 | end
212 |
213 | describe port(25_672) do
214 | xit 'Is on 55672 instead on older rmq versions' do
215 | is_expected.to be_listening.on('0.0.0.0').with('tcp')
216 | end
217 | end
218 | end
219 | end
220 |
--------------------------------------------------------------------------------
/spec/acceptance/clustering_spec.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | require 'spec_helper_acceptance'
4 |
5 | describe 'rabbitmq clustering' do
6 | context 'rabbitmq::wipe_db_on_cookie_change => false' do
7 | it 'runs successfully' do
8 | pp = <<-EOS
9 | class { 'rabbitmq':
10 | cluster => { 'name' => 'rabbit_cluster', 'init_node' => $facts['networking']['fqdn'] },
11 | config_cluster => true,
12 | cluster_nodes => ['rabbit1', 'rabbit2'],
13 | cluster_node_type => 'ram',
14 | erlang_cookie => 'TESTCOOKIE',
15 | wipe_db_on_cookie_change => false,
16 | }
17 | EOS
18 |
19 | apply_manifest(pp, expect_failures: true)
20 | end
21 |
22 | describe file('/var/lib/rabbitmq/.erlang.cookie') do
23 | it { is_expected.not_to contain 'TESTCOOKIE' }
24 | end
25 | end
26 |
27 | context 'rabbitmq::wipe_db_on_cookie_change => true' do
28 | it 'runs successfully' do
29 | pp = <<-EOS
30 | class { 'rabbitmq':
31 | cluster => { 'name' => 'rabbit_cluster', 'init_node' => $facts['networking']['fqdn'] },
32 | config_cluster => true,
33 | cluster_nodes => ['rabbit1', 'rabbit2'],
34 | cluster_node_type => 'ram',
35 | erlang_cookie => 'TESTCOOKIE',
36 | wipe_db_on_cookie_change => true,
37 | }
38 | EOS
39 |
40 | apply_manifest(pp, catch_failures: true)
41 | end
42 |
43 | describe file('/etc/rabbitmq/rabbitmq.config') do
44 | it { is_expected.to be_file }
45 | it { is_expected.to contain 'cluster_nodes' }
46 | it { is_expected.to contain 'rabbit@rabbit1' }
47 | it { is_expected.to contain 'rabbit@rabbit2' }
48 | it { is_expected.to contain 'ram' }
49 | end
50 |
51 | describe file('/var/lib/rabbitmq/.erlang.cookie') do
52 | it { is_expected.to be_file }
53 | it { is_expected.to contain 'TESTCOOKIE' }
54 | end
55 |
56 | describe 'rabbitmq_cluster' do
57 | context 'cluster_name => rabbit_cluster' do
58 | it 'cluster has name' do
59 | shell('rabbitmqctl -q cluster_status') do |r|
60 | expect(r.stdout).to match(%r!({cluster_name,<<"rabbit_cluster">>}|^Cluster name: rabbit_cluster$)!)
61 | expect(r.exit_code).to be_zero
62 | end
63 | end
64 | end
65 | end
66 | end
67 |
68 | context 'rabbitmq::cluster[:local_node] = foobar' do
69 | it 'runs successfully' do
70 | pp = <<-EOS
71 | # Needed to avoid nxdomain error
72 | host { 'foobar':
73 | ip => '127.0.0.1',
74 | }
75 | class { 'rabbitmq':
76 | cluster => { 'name' => 'rabbit_cluster', 'init_node' => 'foobar', 'local_node' => 'foobar' },
77 | config_cluster => true,
78 | cluster_nodes => ['foobar', 'rabbit2'],
79 | cluster_node_type => 'ram',
80 | environment_variables => { 'NODENAME' => 'rabbit@foobar' },
81 | erlang_cookie => 'TESTCOOKIE',
82 | }
83 | EOS
84 |
85 | apply_manifest(pp, catch_failures: true)
86 | end
87 | end
88 | end
89 |
--------------------------------------------------------------------------------
/spec/acceptance/delete_guest_user_spec.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | require 'spec_helper_acceptance'
4 |
5 | describe 'rabbitmq with delete_guest_user' do
6 | context 'delete_guest_user' do
7 | it 'runs successfully' do
8 | pp = <<-EOS
9 | class { 'rabbitmq':
10 | port => 5672,
11 | delete_guest_user => true,
12 | }
13 | EOS
14 |
15 | apply_manifest(pp, catch_failures: true)
16 | shell('rabbitmqctl list_users > /tmp/rabbitmqctl_users')
17 | end
18 |
19 | describe file('/tmp/rabbitmqctl_users') do
20 | it { is_expected.to be_file }
21 | it { is_expected.not_to contain 'guest' }
22 | end
23 | end
24 | end
25 |
--------------------------------------------------------------------------------
/spec/acceptance/parameter_spec.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | require 'spec_helper_acceptance'
4 |
5 | describe 'rabbitmq parameter on a vhost:' do
6 | context 'create parameter resource' do
7 | it 'runs successfully' do
8 | pp = <<-EOS
9 | class { 'rabbitmq':
10 | service_manage => true,
11 | port => 5672,
12 | delete_guest_user => true,
13 | admin_enable => true,
14 | }
15 |
16 | rabbitmq_plugin { [ 'rabbitmq_federation_management', 'rabbitmq_federation' ]:
17 | ensure => present
18 | } ~> Service['rabbitmq-server']
19 |
20 | rabbitmq_vhost { 'fedhost':
21 | ensure => present,
22 | } ->
23 |
24 | rabbitmq_parameter { 'documentumFed@fedhost':
25 | component_name => 'federation-upstream',
26 | value => {
27 | 'uri' => 'amqp://server',
28 | 'expires' => '3600000',
29 | },
30 | }
31 | EOS
32 |
33 | apply_manifest(pp, catch_failures: true)
34 | apply_manifest(pp, catch_changes: true)
35 | end
36 |
37 | it 'has the parameter' do
38 | shell('rabbitmqctl list_parameters -p fedhost') do |r|
39 | expect(r.stdout).to match(%r{federation-upstream.*documentumFed.*expires.*3600000})
40 | expect(r.exit_code).to be_zero
41 | end
42 | end
43 | end
44 |
45 | context 'destroy parameter resource' do
46 | it 'runs successfully' do
47 | pp = <<-EOS
48 | rabbitmq_parameter { 'documentumFed@fedhost':
49 | ensure => absent,
50 | }
51 | EOS
52 |
53 | apply_manifest(pp, catch_failures: true)
54 | apply_manifest(pp, catch_changes: true)
55 | end
56 |
57 | it 'does not have the parameter' do
58 | shell('rabbitmqctl list_parameters -q') do |r|
59 | expect(r.stdout).not_to match(%r{documentumFed\s+})
60 | end
61 | end
62 | end
63 | end
64 |
--------------------------------------------------------------------------------
/spec/acceptance/policy_spec.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | require 'spec_helper_acceptance'
4 |
5 | describe 'rabbitmq policy on a vhost:' do
6 | context 'create policy resource' do
7 | it 'runs successfully' do
8 | pp = <<-EOS
9 | class { 'rabbitmq':
10 | service_manage => true,
11 | port => 5672,
12 | delete_guest_user => true,
13 | admin_enable => true,
14 | } ->
15 |
16 | rabbitmq_vhost { 'myhost':
17 | ensure => present,
18 | } ->
19 |
20 | rabbitmq_policy { 'ha-all@myhost':
21 | pattern => '.*',
22 | priority => 0,
23 | applyto => 'all',
24 | definition => {
25 | 'ha-mode' => 'all',
26 | 'ha-sync-mode' => 'automatic',
27 | },
28 | }
29 |
30 | rabbitmq_policy { 'eu-federation@myhost':
31 | pattern => '^eu\\.',
32 | priority => 0,
33 | applyto => 'all',
34 | definition => {
35 | 'federation-upstream-set' => 'all',
36 | },
37 | }
38 | EOS
39 |
40 | apply_manifest(pp, catch_failures: true)
41 | apply_manifest(pp, catch_changes: true)
42 |
43 | # Apply twice to ensure no changes the second time.
44 | apply_manifest(pp, catch_failures: true)
45 | expect(apply_manifest(pp, catch_changes: true).exit_code).to be_zero
46 | end
47 |
48 | it 'has the policy' do
49 | shell('rabbitmqctl list_policies -p myhost') do |r|
50 | expect(r.stdout).to match(%r{myhost.*ha-all.*ha-sync-mode})
51 | expect(r.stdout).to match(%r{myhost.*eu-federation})
52 | expect(r.exit_code).to be_zero
53 | end
54 | end
55 | end
56 | end
57 |
--------------------------------------------------------------------------------
/spec/acceptance/rabbitmqadmin_spec.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | require 'spec_helper_acceptance'
4 |
5 | describe 'rabbitmq::install::rabbitmqadmin class' do
6 | context 'downloads the cli tools' do
7 | it 'runs successfully' do
8 | pp = <<-EOS
9 | class { 'rabbitmq':
10 | admin_enable => true,
11 | service_manage => true,
12 | }
13 | EOS
14 |
15 | apply_manifest(pp, catch_failures: true)
16 | end
17 |
18 | describe file('/var/lib/rabbitmq/rabbitmqadmin') do
19 | it { is_expected.to be_file }
20 | end
21 | end
22 |
23 | context 'does nothing if service is unmanaged' do
24 | it 'runs successfully' do
25 | pp = <<-EOS
26 | class { 'rabbitmq':
27 | admin_enable => true,
28 | service_manage => false,
29 | }
30 | EOS
31 |
32 | shell('rm -f /var/lib/rabbitmq/rabbitmqadmin')
33 | apply_manifest(pp, catch_failures: true)
34 | end
35 |
36 | describe file('/var/lib/rabbitmq/rabbitmqadmin') do
37 | it { is_expected.not_to be_file }
38 | end
39 | end
40 |
41 | context 'works with specified default credentials' do
42 | it 'runs successfully' do
43 | # make sure credential change takes effect before admin_enable
44 | pp_pre = <<-EOS
45 | class { 'rabbitmq':
46 | service_manage => true,
47 | default_user => 'foobar',
48 | default_pass => 'bazblam',
49 | }
50 | EOS
51 |
52 | pp = <<-EOS
53 | class { 'rabbitmq':
54 | admin_enable => true,
55 | service_manage => true,
56 | default_user => 'foobar',
57 | default_pass => 'bazblam',
58 | }
59 | EOS
60 |
61 | shell('rm -f /var/lib/rabbitmq/rabbitmqadmin')
62 | apply_manifest(pp_pre, catch_failures: true)
63 | apply_manifest(pp, catch_failures: true)
64 | end
65 |
66 | describe file('/var/lib/rabbitmq/rabbitmqadmin') do
67 | it { is_expected.to be_file }
68 | end
69 | end
70 | end
71 |
--------------------------------------------------------------------------------
/spec/acceptance/user_spec.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | require 'spec_helper_acceptance'
4 |
5 | describe 'rabbitmq user:' do
6 | context 'create user resource' do
7 | it 'runs successfully' do
8 | pp = <<-EOS
9 | class { 'rabbitmq':
10 | service_manage => true,
11 | port => 5672,
12 | delete_guest_user => true,
13 | admin_enable => true,
14 | } ->
15 |
16 | rabbitmq_user { 'dan':
17 | admin => true,
18 | password => 'bar',
19 | }
20 | EOS
21 |
22 | apply_manifest(pp, catch_failures: true)
23 | apply_manifest(pp, catch_changes: true)
24 | end
25 |
26 | it 'has the user' do
27 | shell('rabbitmqctl list_users -q') do |r|
28 | expect(r.stdout).to match(%r{dan.*administrator})
29 | expect(r.exit_code).to be_zero
30 | end
31 | end
32 | end
33 |
34 | context 'destroy user resource' do
35 | it 'runs successfully' do
36 | pp = <<-EOS
37 | rabbitmq_user { 'dan':
38 | ensure => absent,
39 | }
40 | EOS
41 |
42 | apply_manifest(pp, catch_failures: true)
43 | apply_manifest(pp, catch_changes: true)
44 | end
45 |
46 | it 'does not have the user' do
47 | shell('rabbitmqctl list_users -q') do |r|
48 | expect(r.stdout).not_to match(%r{dan\s+})
49 | end
50 | end
51 | end
52 | end
53 |
--------------------------------------------------------------------------------
/spec/acceptance/vhost_spec.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | require 'spec_helper_acceptance'
4 |
5 | describe 'rabbitmq vhost:' do
6 | context 'create vhost resource' do
7 | it 'runs successfully' do
8 | pp = <<-EOS
9 | class { 'rabbitmq':
10 | service_manage => true,
11 | port => 5672,
12 | delete_guest_user => true,
13 | admin_enable => true,
14 | }
15 |
16 | -> rabbitmq_vhost { 'myhost':
17 | ensure => present,
18 | }
19 | EOS
20 |
21 | apply_manifest(pp, catch_failures: true)
22 | apply_manifest(pp, catch_changes: true)
23 | end
24 |
25 | it 'has the vhost' do
26 | shell('rabbitmqctl list_vhosts') do |r|
27 | expect(r.stdout).to match(%r{myhost})
28 | expect(r.exit_code).to be_zero
29 | end
30 | end
31 | end
32 | end
33 |
--------------------------------------------------------------------------------
/spec/spec_helper.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | # Managed by modulesync - DO NOT EDIT
4 | # https://voxpupuli.org/docs/updating-files-managed-with-modulesync/
5 |
6 | # puppetlabs_spec_helper will set up coverage if the env variable is set.
7 | # We want to do this if lib exists and it hasn't been explicitly set.
8 | ENV['COVERAGE'] ||= 'yes' if Dir.exist?(File.expand_path('../lib', __dir__))
9 |
10 | require 'voxpupuli/test/spec_helper'
11 |
12 | RSpec.configure do |c|
13 | c.facterdb_string_keys = true
14 | c.mock_with :mocha
15 | end
16 |
17 | add_mocked_facts!
18 |
19 | if File.exist?(File.join(__dir__, 'default_module_facts.yml'))
20 | facts = YAML.safe_load(File.read(File.join(__dir__, 'default_module_facts.yml')))
21 | facts&.each do |name, value|
22 | add_custom_fact name.to_sym, value
23 | end
24 | end
25 |
26 | require 'spec_helper_local'
27 | Dir['./spec/support/spec/**/*.rb'].sort.each { |f| require f }
28 |
--------------------------------------------------------------------------------
/spec/spec_helper_acceptance.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | require 'voxpupuli/acceptance/spec_helper_acceptance'
4 |
5 | configure_beaker do |host|
6 | case fact_on(host, 'os.family')
7 | when 'Debian'
8 | install_puppet_module_via_pmt_on(host, 'puppetlabs-apt', '>= 9.0.0 < 10.0.0')
9 | when 'RedHat'
10 | if fact_on(host, 'os.selinux.enabled')
11 | # Make sure selinux is disabled so the tests work.
12 | on host, puppet('resource', 'exec', 'setenforce 0', 'path=/bin:/sbin:/usr/bin:/usr/sbin', 'onlyif=which setenforce && getenforce | grep Enforcing')
13 | end
14 | end
15 |
16 | # Fake certs
17 | on host, 'echo "-----BEGIN RSA PRIVATE KEY-----
18 | MIICXAIBAAKBgQDw1uXI+EAgxk4dOxArPqMNnnCQqmXeQ61XQQXoAgWWjRvY4LAJ
19 | 4ALoACYWFlWVKQkLLQfQ2YYM3vNDG/eYfL2tjhp9APeJrJYJEcbmr5COURtuIh/Z
20 | fVKRgV5vtOMdlAHS0HFpk/DP1g520Da9wKwv2nDbfRui0y0ImPWz1uqK8wIDAQAB
21 | AoGBAJ/cNMgyJ/bZSk5SvwfFWtuWWGdeA6IF0BBDo9T9SpJE9b/+XDshyywNtToh
22 | 9wq8Izmc2TxCtpzifBwGe1FnM0qvioQhwQwJsGa4JJFzSkIt/MgPmojzutnP59RJ
23 | ozjCgAahX6xEkB6Kn/b2S6D7jgixyMTQ3FdPKq6lJVhXz6Q5AkEA+tSgg/xhrcTs
24 | 5W//hYZP/xjrE27xXzfkNrr/cAtVH5ZM2j2qqKFv3wEn9tAKrUvM+KNDhEjgLUSd
25 | MjvvH5DYZQJBAPXNjsg4AG09KqWbvcbB2Cgaf6RRTAe+Hx6A7aB01OQohc5uF0ws
26 | cPxZ8CE/KDbHtNSlx1MAvn8IOoitA06s5HcCQErP/mw/a3bjxHCOXh0aOWPxr7Ol
27 | JHLs/bFhRuzJRINeVd/GAs+3DuHpu1y/ImAbuq/yKiIbhlmaHHSuMZ0tm40CQHHi
28 | FzE0oR37pPKtwbOAxEFwZYsgD3XW5Fwhp/cbqjc7fyMxZqHoRUDl+pesx1j6FhIf
29 | 7MXMJnZ8vYHthwbAm+kCQHFH0HULyNcki4zEYSqiLaVMcbB7QybQmBBDA0mJR2HO
30 | KYdYDeFG3kfeBOReFM9jOt39OBS/nNP0GXFBJU2ahpQ=
31 | -----END RSA PRIVATE KEY-----" > /tmp/rabbitmq.key'
32 | on host, 'echo "-----BEGIN CERTIFICATE-----
33 | MIIEYTCCAkmgAwIBAgIQVAIiKvJ6YmTSszWEfassuDANBgkqhkiG9w0BAQUFADCB
34 | qjELMAkGA1UEBhMCVVMxEzARBgNVBAgMCkNhbGlmb3JuaWExFDASBgNVBAcMC0xv
35 | cyBBbmdlbGVzMRUwEwYDVQQKDAxBY21lIFdpZGdldHMxETAPBgNVBAsMCFNlY3Vy
36 | aXR5MR0wGwYDVQQDDBRyYWJiaXRtcS5leGFtcGxlLmNvbTEnMCUGCSqGSIb3DQEJ
37 | ARYYcm9nZXIucmFiYml0QGV4YW1wbGUuY29tMB4XDTE3MDkxMzAzMzExMloXDTI3
38 | MDkxMTAzMzExMlowgZUxCzAJBgNVBAYTAlVTMQswCQYDVQQIDAJDQTEQMA4GA1UE
39 | BwwHQ2hpY2FnbzENMAsGA1UECgwEQWNtZTEQMA4GA1UECwwHV2lkZ2V0czEdMBsG
40 | A1UEAwwUcmFiYml0bXEuZXhhbXBsZS5jb20xJzAlBgkqhkiG9w0BCQEWGHJvZ2Vy
41 | LnJhYmJpdEBleGFtcGxlLmNvbTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA
42 | 8NblyPhAIMZOHTsQKz6jDZ5wkKpl3kOtV0EF6AIFlo0b2OCwCeAC6AAmFhZVlSkJ
43 | Cy0H0NmGDN7zQxv3mHy9rY4afQD3iayWCRHG5q+QjlEbbiIf2X1SkYFeb7TjHZQB
44 | 0tBxaZPwz9YOdtA2vcCsL9pw230botMtCJj1s9bqivMCAwEAAaMaMBgwCQYDVR0T
45 | BAIwADALBgNVHQ8EBAMCBeAwDQYJKoZIhvcNAQEFBQADggIBAIPXqHlxbo+BpBWz
46 | H+E7lFDYZkUQD8c34jybxZbwya7od/f9x5jU3F/+6g1Y7A8NAPPxbs+m3Sye0/sz
47 | WmEz+smKFseGVPWQJ6NgvYJjr8P/MpBUfA7zkkaKs2uuTbPx0tgU1+XGluC1hsZ+
48 | KQCI0LIEGQlSuT3miPSYL6MPR9o/PTp6TPlYGbL+LLNQedriZRLuiUpOWJzsFyz/
49 | CcdayANtlWxhuy50A9qUwAa5RzgIJnqfxk5OYuJHq7+p1oCKk+XhgHccHHq7t97M
50 | Ye/xC18NDTMKkAiggCad0+kYTUgUYnuwvYg4eRpQytsncp7Ck83JChb56eJKlsj1
51 | HnEkQDyi1B/cKxRKwG81fzkSgw7+0nFY6GAIaGz1GdYBkoxlzN9JNd3/MmS+xAtm
52 | HXtCqkTWUJQ5ZBinszauPtG4Inu6H28blstlqGjzKTzwo1w8N27shii14IhEHhEV
53 | tVRxA+ORIt14fZrl04AROsYLqJxqBHy8vJEX4OMm2JTzaO2KdPwEi2gmQK0SkfR8
54 | TCQc43SF2rqpYs3ZE4fPNlyQR3ZCUcYwjv99s6Nz0Ue4vD9+PuT0McE8NtMgiAMf
55 | DQqmYIMEiYNm15qKW6jJaY7VMUPGNohfEvubsWPlXPQ6/I7e9bNyk5OnA6OGi4qz
56 | M2Fcgn+pqLU7M+epynzgz4bsPsEw
57 | -----END CERTIFICATE-----" > /tmp/rabbitmq.crt'
58 | on host, 'echo "-----BEGIN CERTIFICATE-----
59 | MIIGKTCCBBGgAwIBAgIJAMCISMDHjBJpMA0GCSqGSIb3DQEBBQUAMIGqMQswCQYD
60 | VQQGEwJVUzETMBEGA1UECAwKQ2FsaWZvcm5pYTEUMBIGA1UEBwwLTG9zIEFuZ2Vs
61 | ZXMxFTATBgNVBAoMDEFjbWUgV2lkZ2V0czERMA8GA1UECwwIU2VjdXJpdHkxHTAb
62 | BgNVBAMMFHJhYmJpdG1xLmV4YW1wbGUuY29tMScwJQYJKoZIhvcNAQkBFhhyb2dl
63 | ci5yYWJiaXRAZXhhbXBsZS5jb20wHhcNMTcwOTEzMDMzMTAyWhcNMjcwOTExMDMz
64 | MTAyWjCBqjELMAkGA1UEBhMCVVMxEzARBgNVBAgMCkNhbGlmb3JuaWExFDASBgNV
65 | BAcMC0xvcyBBbmdlbGVzMRUwEwYDVQQKDAxBY21lIFdpZGdldHMxETAPBgNVBAsM
66 | CFNlY3VyaXR5MR0wGwYDVQQDDBRyYWJiaXRtcS5leGFtcGxlLmNvbTEnMCUGCSqG
67 | SIb3DQEJARYYcm9nZXIucmFiYml0QGV4YW1wbGUuY29tMIICIjANBgkqhkiG9w0B
68 | AQEFAAOCAg8AMIICCgKCAgEA2WBjjypMwd4QU2m2K3ChuviDjY/4/c/cwcJBiM2l
69 | ibQdTO77is5Ub017/z+/Y9kZ4BMO86G97nkafG+mqyuWQj7kaOOAtaZ72Vz4Z2wl
70 | 3eij08OZO4rr3WvYP1VPqgM0FuGxA3iIuP1wl+IhaHLLH+HW5wsnl74pdBC+q7lv
71 | FKgd1xtCR0bWXVPbiYUi70rL2VA5j+Tp7gJy2XL0/tr3j+KSmqm6zKPrrl4xSLKW
72 | AZ0o8PFxO9eev5qxf9YYa8LGj7nNLpaqD77ituD27AYdQ4nIaRia4WXyJpyUQ6RS
73 | z87JsKZELZnQkd6EOXL5C/H0AZHz6KGbU7f4Zpxg0dj0vArunSxoMZRICfuGespi
74 | KGRCENL12HP7kAM+kdoWXcN5xd+NF+IJqoKORX/P9a8VNA3xn5EGMX/b+gcVOpB3
75 | 0H/gWMYI8M2rnFSDWw+1+qgJfV1meRM6+bj4Fab9mFxMPuqPCsd4YUQdSEOlV7L+
76 | FpixpbOUEUIGSGCkE0tBdJ2zpStAnB3TsrjYhSU1GsevrdKEa5msfkHTDpZV/9EY
77 | AXo6WMWHWQe+joxnQzr9r8dlmdsyH0mN+cDxUmlQIwwvHqEtf7CVkN0cx7qKPhQ0
78 | vHX2NmlfmpgTf5LKnC4xrz8M8OsMfMV5efck0lLYuGKe4wFiBdCoTQvHRuCBncP+
79 | npMCAwEAAaNQME4wHQYDVR0OBBYEFCkQ7/iSfDsHVL0UcA9vuEB5mqL5MB8GA1Ud
80 | IwQYMBaAFCkQ7/iSfDsHVL0UcA9vuEB5mqL5MAwGA1UdEwQFMAMBAf8wDQYJKoZI
81 | hvcNAQEFBQADggIBAEpHP9B7YbsykJ0mMDgXtUog7ZgY5qMf7YFnNrF7Gj0RRRsa
82 | O9oMSyQbOH6hEgr4b89Vval0ojKg0nWjP/KO73IRwb/eXewWV2THJaKW8Nj0T3mP
83 | Zai2OHEKIk33qBlAOMbgjL5GTwAbWuwPg8hQYySscOGblknQEdCLweRoCCU9m0dA
84 | EgQpemsELJoY0i2HkrAVK9+FCmxr0N4ApEckw/+KZxL/Yb0Sz3R3+0FM3JGkbdgi
85 | 2zP5xBEpJszHZqpwsxSwrLbnACrwv7xdxso/ojiW2MWPGqB/g3hHY9PexV732ZNK
86 | sRN2WJmRQ1G1RzKs8pi352hbra3WDmeEb0AQEuda6sqx6mu0EiomKN5JOq+pltyK
87 | PvQuBvJV04HwFqpTm7wAJprF1F+9y1B4PDt8c+/CnMBKMOJ9nv84qZEq2ihp65LK
88 | valeoetcimRCEJ5xnqGCza/sSDHjUMUvMhwMJdq56t0zKMk5pFH6lHxzgAKzX3Gt
89 | pct+50AzBHUSn0zpB6QRBow2MddivGmTs1IOFdWaSj+Mfdb6phln1Hkv+KW2Wizv
90 | I28L690yK+Bnk1ezGs+ln6yxiWOdnurckaLkTj6/JFw2x5q/uaTXOxjG/YKKpMQE
91 | Fq8uI2+DbX/zW18ZIEv6UloGEEWbLO1427+Yyb/THMczWYyH20PTyzT8zFOt
92 | -----END CERTIFICATE-----" > /tmp/cacert.crt'
93 | end
94 |
95 | shared_examples 'an idempotent resource' do
96 | it 'applies with no errors' do
97 | apply_manifest(pp, catch_failures: true)
98 | end
99 |
100 | it 'applies a second time without changes' do
101 | apply_manifest(pp, catch_changes: true)
102 | end
103 | end
104 |
--------------------------------------------------------------------------------
/spec/spec_helper_local.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | add_custom_fact :rabbitmq_version, '3.6.1' # puppet-rabbitmq
4 | add_custom_fact :erl_ssl_path, '/usr/lib64/erlang/lib/ssl-7.3.3.1/ebin' # puppet-rabbitmq
5 |
--------------------------------------------------------------------------------
/spec/unit/facter/util/fact_erl_ssl_path_spec.rb:
--------------------------------------------------------------------------------
1 | # rubocop:disable Style/FrozenStringLiteralComment
2 |
3 | require 'spec_helper'
4 |
5 | describe Facter::Util::Fact do
6 | before { Facter.clear }
7 |
8 | describe 'erl_ssl_path' do
9 | context 'with valid value' do
10 | it do
11 | Facter::Util::Resolution.expects(:which).with('erl').returns(true)
12 | Facter::Core::Execution.expects(:execute).with("erl -eval 'io:format(\"~p\", [code:lib_dir(ssl, ebin)]),halt().' -noshell").returns('"/usr/lib64/erlang/lib/ssl-5.3.3/ebin"')
13 | expect(Facter.fact(:erl_ssl_path).value).to eq('/usr/lib64/erlang/lib/ssl-5.3.3/ebin')
14 | end
15 | end
16 |
17 | context 'with error message' do
18 | it do
19 | Facter::Util::Resolution.expects(:which).with('erl').returns(true)
20 | Facter::Core::Execution.expects(:execute).with("erl -eval 'io:format(\"~p\", [code:lib_dir(ssl, ebin)]),halt().' -noshell").returns('{error,bad_name}')
21 | expect(Facter.fact(:erl_ssl_path).value).to be_nil
22 | end
23 | end
24 |
25 | context 'with erl not present' do
26 | it do
27 | Facter::Util::Resolution.expects(:which).with('erl').returns(false)
28 | expect(Facter.fact(:erl_ssl_path).value).to be_nil
29 | end
30 | end
31 | end
32 | end
33 |
34 | # rubocop:enable Style/FrozenStringLiteralComment
35 |
--------------------------------------------------------------------------------
/spec/unit/facter/util/fact_rabbitmq_clustername_spec.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | require 'spec_helper'
4 |
5 | describe Facter::Util::Fact do
6 | before do
7 | Facter.clear
8 | end
9 |
10 | describe 'rabbitmq_clusternam' do
11 | context 'with value' do
12 | it do
13 | Facter::Util::Resolution.expects(:which).with('rabbitmqctl').returns(true)
14 | Facter::Core::Execution.expects(:execute).with('rabbitmqctl -q cluster_status 2>&1').returns(' {cluster_name,<<"monty">>},')
15 | expect(Facter.fact(:rabbitmq_clustername).value).to eq('monty')
16 | end
17 | end
18 |
19 | context 'with dashes in hostname' do
20 | it do
21 | Facter::Util::Resolution.expects(:which).with('rabbitmqctl').returns(true)
22 | Facter::Core::Execution.expects(:execute).with('rabbitmqctl -q cluster_status 2>&1').returns('Cluster name: rabbit-1')
23 | expect(Facter.fact(:rabbitmq_clustername).value).to eq('rabbit-1')
24 | end
25 | end
26 |
27 | context 'with dashes in clustername/hostname' do
28 | it do
29 | Facter::Util::Resolution.expects(:which).with('rabbitmqctl').returns(true)
30 | Facter::Core::Execution.expects(:execute).with('rabbitmqctl -q cluster_status 2>&1').returns(' {cluster_name,<<"monty-python@rabbit-1">>},')
31 | expect(Facter.fact(:rabbitmq_clustername).value).to eq('monty-python@rabbit-1')
32 | end
33 | end
34 |
35 | context 'with quotes around node name' do
36 | it do
37 | Facter::Util::Resolution.expects(:which).with('rabbitmqctl').returns(true)
38 | Facter::Core::Execution.expects(:execute).with('rabbitmqctl -q cluster_status 2>&1').returns("monty\npython\nCluster name: 'monty@rabbit-1'\nend\nof\nfile")
39 | expect(Facter.fact(:rabbitmq_clustername).value).to eq("'monty@rabbit-1'")
40 | end
41 | end
42 |
43 | context 'rabbitmq is not running' do
44 | it do
45 | error_string = <<~EOS
46 | Status of node 'monty@rabbit-1' ...
47 | Error: unable to connect to node 'monty@rabbit-1': nodedown
48 |
49 | DIAGNOSTICS
50 | ===========
51 |
52 | attempted to contact: ['monty@rabbit-1']
53 |
54 | monty@rabbit-1:
55 | * connected to epmd (port 4369) on centos-7-x64
56 | * epmd reports: node 'rabbit' not running at all
57 | no other nodes on centos-7-x64
58 | * suggestion: start the node
59 |
60 | current node details:
61 | - node name: 'rabbitmq-cli-73@centos-7-x64'
62 | - home dir: /var/lib/rabbitmq
63 | - cookie hash: 6WdP0nl6d3HYqA5vTKMkIg==
64 |
65 | EOS
66 | Facter::Util::Resolution.expects(:which).with('rabbitmqctl').returns(true)
67 | Facter::Core::Execution.expects(:execute).with('rabbitmqctl -q cluster_status 2>&1').returns(error_string)
68 | expect(Facter.fact(:rabbitmq_clustername).value).to be_nil
69 | end
70 | end
71 |
72 | context 'rabbitmqctl is not in path' do
73 | it do
74 | Facter::Util::Resolution.expects(:which).with('rabbitmqctl').returns(false)
75 | expect(Facter.fact(:rabbitmq_clustername).value).to be_nil
76 | end
77 | end
78 | end
79 | end
80 |
--------------------------------------------------------------------------------
/spec/unit/facter/util/fact_rabbitmq_nodename_spec.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | require 'spec_helper'
4 |
5 | describe Facter::Util::Fact do
6 | before { Facter.clear }
7 |
8 | describe 'rabbitmq_nodename' do
9 | context 'with value' do
10 | it do
11 | Facter::Util::Resolution.expects(:which).with('rabbitmqctl').returns(true)
12 | Facter::Core::Execution.expects(:execute).with('rabbitmqctl status 2>&1').returns('Status of node monty@rabbit1 ...')
13 | expect(Facter.fact(:rabbitmq_nodename).value).to eq('monty@rabbit1')
14 | end
15 | end
16 |
17 | context 'with dashes in hostname' do
18 | it do
19 | Facter::Util::Resolution.expects(:which).with('rabbitmqctl').returns(true)
20 | Facter::Core::Execution.expects(:execute).with('rabbitmqctl status 2>&1').returns('Status of node monty@rabbit-1 ...')
21 | expect(Facter.fact(:rabbitmq_nodename).value).to eq('monty@rabbit-1')
22 | end
23 | end
24 |
25 | context 'with dashes in nodename/hostname' do
26 | it do
27 | Facter::Util::Resolution.expects(:which).with('rabbitmqctl').returns(true)
28 | Facter::Core::Execution.expects(:execute).with('rabbitmqctl status 2>&1').returns('Status of node monty-python@rabbit-1 ...')
29 | expect(Facter.fact(:rabbitmq_nodename).value).to eq('monty-python@rabbit-1')
30 | end
31 | end
32 |
33 | context 'with quotes around node name' do
34 | it do
35 | Facter::Util::Resolution.expects(:which).with('rabbitmqctl').returns(true)
36 | Facter::Core::Execution.expects(:execute).with('rabbitmqctl status 2>&1').returns('Status of node \'monty@rabbit-1\' ...')
37 | expect(Facter.fact(:rabbitmq_nodename).value).to eq('monty@rabbit-1')
38 | end
39 | end
40 |
41 | context 'without trailing points' do
42 | it do
43 | Facter::Util::Resolution.expects(:which).with('rabbitmqctl').returns(true)
44 | Facter::Core::Execution.expects(:execute).with('rabbitmqctl status 2>&1').returns('Status of node monty@rabbit-1')
45 | expect(Facter.fact(:rabbitmq_nodename).value).to eq('monty@rabbit-1')
46 | end
47 | end
48 |
49 | context 'rabbitmq is not running' do
50 | it do
51 | error_string = <<~EOS
52 | Status of node 'monty@rabbit-1' ...
53 | Error: unable to connect to node 'monty@rabbit-1': nodedown
54 |
55 | DIAGNOSTICS
56 | ===========
57 |
58 | attempted to contact: ['monty@rabbit-1']
59 |
60 | monty@rabbit-1:
61 | * connected to epmd (port 4369) on centos-7-x64
62 | * epmd reports: node 'rabbit' not running at all
63 | no other nodes on centos-7-x64
64 | * suggestion: start the node
65 |
66 | current node details:
67 | - node name: 'rabbitmq-cli-73@centos-7-x64'
68 | - home dir: /var/lib/rabbitmq
69 | - cookie hash: 6WdP0nl6d3HYqA5vTKMkIg==
70 |
71 | EOS
72 | Facter::Util::Resolution.expects(:which).with('rabbitmqctl').returns(true)
73 | Facter::Core::Execution.expects(:execute).with('rabbitmqctl status 2>&1').returns(error_string)
74 | expect(Facter.fact(:rabbitmq_nodename).value).to eq('monty@rabbit-1')
75 | end
76 | end
77 |
78 | context 'rabbitmqctl is not in path' do
79 | it do
80 | Facter::Util::Resolution.expects(:which).with('rabbitmqctl').returns(false)
81 | expect(Facter.fact(:rabbitmq_nodename).value).to be_nil
82 | end
83 | end
84 | end
85 | end
86 |
--------------------------------------------------------------------------------
/spec/unit/facter/util/fact_rabbitmq_plugins_dirs_spec.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | require 'spec_helper'
4 |
5 | describe Facter::Util::Fact do
6 | before { Facter.clear }
7 |
8 | describe 'rabbitmq_plugins_dirs' do
9 | context 'with multiple plugins dirs' do
10 | it do
11 | Facter::Util::Resolution.expects(:which).with('rabbitmqctl').returns(true)
12 | Facter::Core::Execution.expects(:execute).with("rabbitmqctl eval 'application:get_env(rabbit, plugins_dir).'").returns('{ok,"/usr/lib/rabbitmq/plugins:/usr/lib/rabbitmq/lib/rabbitmq_server-3.7.10/plugins"}')
13 | expect(Facter.fact(:rabbitmq_plugins_dirs).value).to contain_exactly('/usr/lib/rabbitmq/plugins', '/usr/lib/rabbitmq/lib/rabbitmq_server-3.7.10/plugins')
14 | end
15 | end
16 |
17 | context 'with only 1 plugins dir' do
18 | it do
19 | Facter::Util::Resolution.expects(:which).with('rabbitmqctl').returns(true)
20 | Facter::Core::Execution.expects(:execute).with("rabbitmqctl eval 'application:get_env(rabbit, plugins_dir).'").returns('{ok,"/usr/lib/rabbitmq/lib/rabbitmq_server-0.0.0/plugins"}')
21 | expect(Facter.fact(:rabbitmq_plugins_dirs).value).to contain_exactly('/usr/lib/rabbitmq/lib/rabbitmq_server-0.0.0/plugins')
22 | end
23 | end
24 |
25 | context 'rabbitmqctl is not in path' do
26 | it do
27 | Facter::Util::Resolution.expects(:which).with('rabbitmqctl').returns(false)
28 | expect(Facter.fact(:rabbitmq_plugins_dirs).value).to be_nil
29 | end
30 | end
31 | end
32 | end
33 |
--------------------------------------------------------------------------------
/spec/unit/facter/util/fact_rabbitmq_version_spec.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | require 'spec_helper'
4 |
5 | describe Facter::Util::Fact do
6 | before do
7 | Facter.clear
8 | end
9 |
10 | describe 'rabbitmq_version' do
11 | context 'with value' do
12 | it do
13 | Facter::Util::Resolution.expects(:which).with('rabbitmqadmin').returns(true)
14 | Facter::Core::Execution.expects(:execute).with('rabbitmqadmin --version 2>&1').returns('rabbitmqadmin 3.6.0')
15 | expect(Facter.fact(:rabbitmq_version).value).to eq('3.6.0')
16 | end
17 | end
18 |
19 | context 'with invalid value' do
20 | it do
21 | Facter::Util::Resolution.expects(:which).with('rabbitmqadmin').returns(true)
22 | Facter::Core::Execution.expects(:execute).with('rabbitmqadmin --version 2>&1').returns('rabbitmqadmin %%VSN%%')
23 | expect(Facter.fact(:rabbitmq_version).value).to be_nil
24 | end
25 | end
26 |
27 | context 'rabbitmqadmin is not in path' do
28 | it do
29 | Facter::Util::Resolution.expects(:which).with('rabbitmqadmin').returns(false)
30 | expect(Facter.fact(:rabbitmq_version).value).to be_nil
31 | end
32 | end
33 | end
34 | end
35 |
--------------------------------------------------------------------------------
/spec/unit/puppet/provider/rabbitmq_binding/rabbitmqadmin_spec.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | require 'spec_helper'
4 |
5 | provider_class = Puppet::Type.type(:rabbitmq_binding).provider(:rabbitmqadmin)
6 | describe provider_class do
7 | let(:resource) do
8 | Puppet::Type::Rabbitmq_binding.new(
9 | name: 'source@target@/',
10 | destination_type: :queue,
11 | routing_key: 'blablub',
12 | arguments: {}
13 | )
14 | end
15 | let(:provider) { provider_class.new(resource) }
16 |
17 | describe '#instances' do
18 | it 'returns instances' do
19 | provider_class.expects(:rabbitmqctl_list).with('vhosts').returns <<~EOT
20 | /
21 | EOT
22 | provider_class.expects(:rabbitmqctl_list).with(
23 | 'bindings', '-p', '/', 'source_name', 'destination_name', 'destination_kind', 'routing_key', 'arguments'
24 | ).returns <<~EOT
25 | exchange\tdst_queue\tqueue\t*\t[]
26 | EOT
27 | instances = provider_class.instances
28 | expect(instances.size).to eq(1)
29 | expect(instances.map do |prov|
30 | {
31 | source: prov.get(:source),
32 | destination: prov.get(:destination),
33 | vhost: prov.get(:vhost),
34 | routing_key: prov.get(:routing_key)
35 | }
36 | end).to eq([
37 | {
38 | source: 'exchange',
39 | destination: 'dst_queue',
40 | vhost: '/',
41 | routing_key: '*'
42 | }
43 | ])
44 | end
45 |
46 | it 'returns multiple instances' do
47 | provider_class.expects(:rabbitmqctl_list).with('vhosts').returns <<~EOT
48 | /
49 | EOT
50 | provider_class.expects(:rabbitmqctl_list).with(
51 | 'bindings', '-p', '/', 'source_name', 'destination_name', 'destination_kind', 'routing_key', 'arguments'
52 | ).returns <<~EOT
53 | exchange\tdst_queue\tqueue\trouting_one\t[]
54 | exchange\tdst_queue\tqueue\trouting_two\t[]
55 | EOT
56 | instances = provider_class.instances
57 | expect(instances.size).to eq(2)
58 | expect(instances.map do |prov|
59 | {
60 | source: prov.get(:source),
61 | destination: prov.get(:destination),
62 | vhost: prov.get(:vhost),
63 | routing_key: prov.get(:routing_key)
64 | }
65 | end).to eq([
66 | {
67 | source: 'exchange',
68 | destination: 'dst_queue',
69 | vhost: '/',
70 | routing_key: 'routing_one'
71 | },
72 | {
73 | source: 'exchange',
74 | destination: 'dst_queue',
75 | vhost: '/',
76 | routing_key: 'routing_two'
77 | }
78 | ])
79 | end
80 | end
81 |
82 | describe 'Test for prefetch error' do
83 | let(:resource) do
84 | Puppet::Type::Rabbitmq_binding.new(
85 | name: 'binding1',
86 | source: 'exchange1',
87 | destination: 'destqueue',
88 | destination_type: :queue,
89 | routing_key: 'blablubd',
90 | arguments: {}
91 | )
92 | end
93 |
94 | it 'exists' do
95 | provider_class.expects(:rabbitmqctl_list).with('vhosts').returns <<~EOT
96 | /
97 | EOT
98 | provider_class.expects(:rabbitmqctl_list).with(
99 | 'bindings', '-p', '/', 'source_name', 'destination_name', 'destination_kind', 'routing_key', 'arguments'
100 | ).returns <<~EOT
101 | exchange\tdst_queue\tqueue\t*\t[]
102 | EOT
103 |
104 | provider_class.prefetch({})
105 | end
106 |
107 | it 'matches' do
108 | # Test resource to match against
109 | provider_class.expects(:rabbitmqctl_list).with('vhosts').returns <<~EOT
110 | /
111 | EOT
112 | provider_class.expects(:rabbitmqctl_list).with(
113 | 'bindings', '-p', '/', 'source_name', 'destination_name', 'destination_kind', 'routing_key', 'arguments'
114 | ).returns <<~EOT
115 | exchange\tdst_queue\tqueue\t*\t[]
116 | EOT
117 |
118 | provider_class.prefetch('binding1' => resource)
119 | end
120 | end
121 |
122 | describe '#create' do
123 | it 'calls rabbitmqadmin to create' do
124 | provider.expects(:rabbitmqadmin).with(
125 | 'declare', 'binding', '--vhost=/', '--user=guest', '--password=guest', '-c', '/etc/rabbitmq/rabbitmqadmin.conf',
126 | 'source=source', 'destination=target', 'arguments={}', 'routing_key=blablub', 'destination_type=queue'
127 | )
128 | provider.create
129 | end
130 |
131 | context 'specifying credentials' do
132 | let(:resource) do
133 | Puppet::Type::Rabbitmq_binding.new(
134 | name: 'source@test2@/',
135 | destination_type: :queue,
136 | routing_key: 'blablubd',
137 | arguments: {},
138 | user: 'colin',
139 | password: 'secret'
140 | )
141 | end
142 | let(:provider) { provider_class.new(resource) }
143 |
144 | it 'calls rabbitmqadmin to create' do
145 | provider.expects(:rabbitmqadmin).with(
146 | 'declare', 'binding', '--vhost=/', '--user=colin', '--password=secret', '-c', '/etc/rabbitmq/rabbitmqadmin.conf',
147 | 'source=source', 'destination=test2', 'arguments={}', 'routing_key=blablubd', 'destination_type=queue'
148 | )
149 | provider.create
150 | end
151 | end
152 |
153 | context 'new queue_bindings' do
154 | let(:resource) do
155 | Puppet::Type::Rabbitmq_binding.new(
156 | name: 'binding1',
157 | source: 'exchange1',
158 | destination: 'destqueue',
159 | destination_type: :queue,
160 | routing_key: 'blablubd',
161 | arguments: {}
162 | )
163 | end
164 | let(:provider) { provider_class.new(resource) }
165 |
166 | it 'calls rabbitmqadmin to create' do
167 | provider.expects(:rabbitmqadmin).with(
168 | 'declare', 'binding', '--vhost=/', '--user=guest', '--password=guest', '-c', '/etc/rabbitmq/rabbitmqadmin.conf',
169 | 'source=exchange1', 'destination=destqueue', 'arguments={}', 'routing_key=blablubd', 'destination_type=queue'
170 | )
171 | provider.create
172 | end
173 | end
174 | end
175 |
176 | describe '#destroy' do
177 | it 'calls rabbitmqadmin to destroy' do
178 | provider.expects(:rabbitmqadmin).with(
179 | 'delete', 'binding', '--vhost=/', '--user=guest', '--password=guest', '-c', '/etc/rabbitmq/rabbitmqadmin.conf',
180 | 'source=source', 'destination_type=queue', 'destination=target', 'properties_key=blablub'
181 | )
182 | provider.destroy
183 | end
184 | end
185 | end
186 |
--------------------------------------------------------------------------------
/spec/unit/puppet/provider/rabbitmq_cli_spec.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | require 'spec_helper'
4 |
5 | require 'puppet/provider/rabbitmq_cli'
6 |
7 | provider_class = Puppet::Provider::RabbitmqCli
8 | describe provider_class do
9 | before do
10 | # Clear the cached version before each test
11 | provider_class.remove_instance_variable(:@rabbitmq_version) \
12 | if provider_class.instance_variable_defined?(:@rabbitmq_version)
13 | end
14 |
15 | it 'gets the RabbitMQ version' do
16 | provider_class.expects(:rabbitmqctl).with('-q', 'status').returns ' [{rabbit,"RabbitMQ","3.7.28"},'
17 | expect(provider_class.rabbitmq_version).to eq('3.7.28')
18 | end
19 |
20 | it 'caches the RabbitMQ version' do
21 | provider_class.expects(:rabbitmqctl).with('-q', 'status').returns ' [{rabbit,"RabbitMQ","3.7.28"},'
22 | v1 = provider_class.rabbitmq_version
23 |
24 | # No second expects for rabbitmqctl as it shouldn't be called again
25 | expect(provider_class.rabbitmq_version).to eq(v1)
26 | end
27 |
28 | it 'gets the RabbitMQ version with version >= 3.8' do
29 | provider_class.expects(:rabbitmqctl).with('-q', 'status').returns 'RabbitMQ version: 3.10.6'
30 | expect(provider_class.rabbitmq_version).to eq('3.10.6')
31 | end
32 |
33 | it 'uses correct list options with RabbitMQ < 3.7.9' do
34 | provider_class.expects(:rabbitmq_version).returns '3.7.8'
35 | provider_class.expects(:rabbitmqctl).with('list_vhost', '-q').returns ''
36 | expect(provider_class.rabbitmqctl_list('vhost')).to eq('')
37 | end
38 |
39 | it 'uses correct list options with RabbitMQ >= 3.7.9' do
40 | provider_class.expects(:rabbitmq_version).returns '3.7.10'
41 | provider_class.expects(:rabbitmqctl).with('list_vhost', '-q', '--no-table-headers').returns ''
42 | expect(provider_class.rabbitmqctl_list('vhost')).to eq('')
43 | end
44 | end
45 |
--------------------------------------------------------------------------------
/spec/unit/puppet/provider/rabbitmq_cluster/rabbitmqctl_spec.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | require 'spec_helper'
4 |
5 | provider_class = Puppet::Type.type(:rabbitmq_cluster).provider(:rabbitmqctl)
6 | describe provider_class do
7 | let(:resource) do
8 | Puppet::Type::Rabbitmq_cluster.new(
9 | name: 'test_cluster',
10 | init_node: 'host1'
11 | )
12 | end
13 | let(:provider) { provider_class.new(resource) }
14 |
15 | describe '#exists?' do
16 | it {
17 | provider.expects(:rabbitmqctl).with('-q', 'cluster_status').returns(
18 | 'Cluster name: test_cluster'
19 | )
20 | expect(provider.exists?).to be true
21 | }
22 | end
23 |
24 | describe '#create on every other node' do
25 | it 'joins a cluster or changes the cluster name' do
26 | provider.expects(:rabbitmqctl).with('stop_app')
27 | provider.expects(:rabbitmqctl).with('join_cluster', 'rabbit@host1', '--disc')
28 | provider.expects(:rabbitmqctl).with('start_app')
29 | provider.create
30 | end
31 | end
32 |
33 | describe '#destroy' do
34 | it 'remove cluster setup' do
35 | provider.expects(:rabbitmqctl).with('stop_app')
36 | provider.expects(:rabbitmqctl).with('reset')
37 | provider.expects(:rabbitmqctl).with('start_app')
38 | provider.destroy
39 | end
40 | end
41 | end
42 |
--------------------------------------------------------------------------------
/spec/unit/puppet/provider/rabbitmq_exchange/rabbitmqadmin_spec.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | require 'spec_helper'
4 |
5 | provider_class = Puppet::Type.type(:rabbitmq_exchange).provider(:rabbitmqadmin)
6 | describe provider_class do
7 | let(:resource) do
8 | Puppet::Type::Rabbitmq_exchange.new(
9 | name: 'test.headers@/',
10 | type: :headers,
11 | internal: :false,
12 | durable: :true,
13 | auto_delete: :false,
14 | arguments: {
15 | 'hash-headers' => 'message-distribution-hash'
16 | }
17 | )
18 | end
19 | let(:provider) { provider_class.new(resource) }
20 |
21 | it 'returns instances' do
22 | provider_class.expects(:rabbitmqctl_list).with('vhosts').returns <<~EOT
23 | /
24 | EOT
25 | provider_class.expects(:rabbitmqctl_list).with('exchanges', '-p', '/', 'name', 'type', 'internal', 'durable', 'auto_delete', 'arguments').returns <<~EOT
26 | direct false true false []
27 | amq.direct direct false true false []
28 | amq.fanout fanout false true false []
29 | amq.headers headers false true false []
30 | amq.match headers false true false []
31 | amq.rabbitmq.log topic true true false []
32 | amq.rabbitmq.trace topic true true false []
33 | amq.topic topic false true false []
34 | test.headers x-consistent-hash false true false [{"hash-header","message-distribution-hash"}]
35 | EOT
36 | instances = provider_class.instances
37 | expect(instances.size).to eq(9)
38 | end
39 |
40 | it 'calls rabbitmqadmin to create as guest' do
41 | 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')
42 | provider.create
43 | end
44 |
45 | it 'calls rabbitmqadmin to destroy' do
46 | provider.expects(:rabbitmqadmin).with('delete', 'exchange', '--vhost=/', '--user=guest', '--password=guest', 'name=test.headers', '-c', '/etc/rabbitmq/rabbitmqadmin.conf')
47 | provider.destroy
48 | end
49 |
50 | context 'specifying credentials' do
51 | let(:resource) do
52 | Puppet::Type::Rabbitmq_exchange.new(
53 | name: 'test.headers@/',
54 | type: :headers,
55 | internal: 'false',
56 | durable: 'true',
57 | auto_delete: 'false',
58 | user: 'colin',
59 | password: 'secret',
60 | arguments: {
61 | 'hash-header' => 'message-distribution-hash'
62 | }
63 | )
64 | end
65 | let(:provider) { provider_class.new(resource) }
66 |
67 | it 'calls rabbitmqadmin to create with credentials' do
68 | 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')
69 | provider.create
70 | end
71 | end
72 | end
73 |
--------------------------------------------------------------------------------
/spec/unit/puppet/provider/rabbitmq_parameter/rabbitmqctl_federation_spec.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | require 'spec_helper'
4 |
5 | provider_class = Puppet::Type.type(:rabbitmq_parameter).provider(:rabbitmqctl)
6 | describe provider_class do
7 | let(:resource) do
8 | Puppet::Type.type(:rabbitmq_parameter).new(
9 | name: 'documentumFederation@/',
10 | component_name: 'federation',
11 | value: {
12 | 'uri' => 'amqp://',
13 | 'expires' => '360000'
14 | }
15 | )
16 | end
17 | let(:provider) { provider_class.new(resource) }
18 |
19 | after do
20 | described_class.instance_variable_set(:@parameters, nil)
21 | end
22 |
23 | describe '#prefetch' do
24 | it 'exists' do
25 | expect(described_class).to respond_to :prefetch
26 | end
27 |
28 | it 'matches' do
29 | provider_class.expects(:rabbitmqctl_list).with('vhosts').returns <<~EOT
30 | /
31 | EOT
32 | provider_class.expects(:rabbitmqctl_list).with('parameters', '-p', '/').returns <<~EOT
33 | federation documentumFederation {"uri":"amqp://","expires":360000}
34 | EOT
35 | provider_class.prefetch('documentumFederation@/' => resource)
36 | end
37 | end
38 |
39 | describe '#instances' do
40 | it 'exists' do
41 | expect(described_class).to respond_to :instances
42 | end
43 |
44 | it 'fail with invalid output from list' do
45 | provider_class.expects(:rabbitmqctl_list).with('vhosts').returns <<~EOT
46 | /
47 | EOT
48 | provider.class.expects(:rabbitmqctl_list).with('parameters', '-p', '/').returns 'foobar'
49 | expect { provider_class.instances }.to raise_error Puppet::Error, %r{cannot parse line from list_parameter}
50 | end
51 |
52 | it 'return no instance' do
53 | provider_class.expects(:rabbitmqctl_list).with('vhosts').returns <<~EOT
54 | /
55 | EOT
56 | provider_class.expects(:rabbitmqctl_list).with('parameters', '-p', '/').returns ''
57 | instances = provider_class.instances
58 | expect(instances.size).to eq(0)
59 | end
60 | end
61 |
62 | describe '#create' do
63 | it 'create parameter' do
64 | provider.expects(:rabbitmqctl).with('set_parameter', '-p', '/', 'federation', 'documentumFederation',
65 | '{"uri":"amqp://","expires":360000}')
66 | provider.create
67 | end
68 | end
69 |
70 | describe '#destroy' do
71 | it 'destroy parameter' do
72 | provider.expects(:rabbitmqctl).with('clear_parameter', '-p', '/', 'federation', 'documentumFederation')
73 | provider.destroy
74 | end
75 | end
76 | end
77 |
--------------------------------------------------------------------------------
/spec/unit/puppet/provider/rabbitmq_parameter/rabbitmqctl_spec.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | require 'spec_helper'
4 |
5 | provider_class = Puppet::Type.type(:rabbitmq_parameter).provider(:rabbitmqctl)
6 | describe provider_class do
7 | let(:resource) do
8 | Puppet::Type.type(:rabbitmq_parameter).new(
9 | name: 'documentumShovel@/',
10 | component_name: 'shovel',
11 | value: {
12 | 'src-uri' => 'amqp://',
13 | 'src-queue' => 'my-queue',
14 | 'dest-uri' => 'amqp://remote-server',
15 | 'dest-queue' => 'another-queue'
16 | }
17 | )
18 | end
19 | let(:provider) { provider_class.new(resource) }
20 |
21 | after do
22 | described_class.instance_variable_set(:@parameters, nil)
23 | end
24 |
25 | describe '#prefetch' do
26 | it 'exists' do
27 | expect(described_class).to respond_to :prefetch
28 | end
29 |
30 | it 'matches' do
31 | provider_class.expects(:rabbitmqctl_list).with('vhosts').returns <<~EOT
32 | /
33 | EOT
34 | provider_class.expects(:rabbitmqctl_list).with('parameters', '-p', '/').returns <<~EOT
35 | shovel documentumShovel {"src-uri":"amqp://","src-queue":"my-queue","dest-uri":"amqp://remote-server","dest-queue":"another-queue"}
36 | EOT
37 | provider_class.prefetch('documentumShovel@/' => resource)
38 | end
39 | end
40 |
41 | describe '#instances' do
42 | it 'exists' do
43 | expect(described_class).to respond_to :instances
44 | end
45 |
46 | it 'fail with invalid output from list' do
47 | provider_class.expects(:rabbitmqctl_list).with('vhosts').returns <<~EOT
48 | /
49 | EOT
50 | provider.class.expects(:rabbitmqctl_list).with('parameters', '-p', '/').returns 'foobar'
51 | expect { provider_class.instances }.to raise_error Puppet::Error, %r{cannot parse line from list_parameter}
52 | end
53 |
54 | it 'return no instance' do
55 | provider_class.expects(:rabbitmqctl_list).with('vhosts').returns <<~EOT
56 | /
57 | EOT
58 | provider_class.expects(:rabbitmqctl_list).with('parameters', '-p', '/').returns ''
59 | instances = provider_class.instances
60 | expect(instances.size).to eq(0)
61 | end
62 |
63 | it 'return one instance' do
64 | provider_class.expects(:rabbitmqctl_list).with('vhosts').returns <<~EOT
65 | /
66 | EOT
67 | provider_class.expects(:rabbitmqctl_list).with('parameters', '-p', '/').returns <<~EOT
68 | shovel documentumShovel {"src-uri":"amqp://","src-queue":"my-queue","dest-uri":"amqp://remote-server","dest-queue":"another-queue"}
69 | EOT
70 | instances = provider_class.instances
71 | expect(instances.size).to eq(1)
72 | expect(instances.map do |prov|
73 | {
74 | name: prov.get(:name),
75 | component_name: prov.get(:component_name),
76 | value: prov.get(:value)
77 | }
78 | end).to eq(
79 | [
80 | {
81 | name: 'documentumShovel@/',
82 | component_name: 'shovel',
83 | value: {
84 | 'src-uri' => 'amqp://',
85 | 'src-queue' => 'my-queue',
86 | 'dest-uri' => 'amqp://remote-server',
87 | 'dest-queue' => 'another-queue'
88 | }
89 | }
90 | ]
91 | )
92 | end
93 |
94 | it 'return multiple instances' do
95 | provider_class.expects(:rabbitmqctl_list).with('vhosts').returns <<~EOT
96 | /
97 | EOT
98 | provider_class.expects(:rabbitmqctl_list).with('parameters', '-p', '/').returns <<~EOT
99 | shovel documentumShovel1 {"src-uri":"amqp://","src-queue":"my-queue","dest-uri":"amqp://remote-server","dest-queue":"another-queue"}
100 | shovel documentumShovel2 {"src-uri":["amqp://cl1","amqp://cl2"],"src-queue":"my-queue","dest-uri":"amqp://remote-server","dest-queue":"another-queue"}
101 | EOT
102 | instances = provider_class.instances
103 | expect(instances.size).to eq(2)
104 | expect(instances.map do |prov|
105 | {
106 | name: prov.get(:name),
107 | component_name: prov.get(:component_name),
108 | value: prov.get(:value)
109 | }
110 | end).to eq(
111 | [
112 | {
113 | name: 'documentumShovel1@/',
114 | component_name: 'shovel',
115 | value: {
116 | 'src-uri' => 'amqp://',
117 | 'src-queue' => 'my-queue',
118 | 'dest-uri' => 'amqp://remote-server',
119 | 'dest-queue' => 'another-queue'
120 | }
121 | },
122 | {
123 | name: 'documentumShovel2@/',
124 | component_name: 'shovel',
125 | value: {
126 | 'src-uri' => ['amqp://cl1', 'amqp://cl2'],
127 | 'src-queue' => 'my-queue',
128 | 'dest-uri' => 'amqp://remote-server',
129 | 'dest-queue' => 'another-queue'
130 | }
131 | }
132 | ]
133 | )
134 | end
135 |
136 | it 'return different instances' do
137 | provider_class.expects(:rabbitmqctl_list).with('vhosts').returns <<~EOT
138 | /
139 | EOT
140 | provider_class.expects(:rabbitmqctl_list).with('parameters', '-p', '/').returns <<~EOT
141 | shovel documentumShovel1 {"src-uri":"amqp://","src-queue":"my-queue","dest-uri":"amqp://remote-server","dest-queue":"another-queue"}
142 | federation documentumFederation2 {"uri":"amqp://","expires":"360000"}
143 | EOT
144 | instances = provider_class.instances
145 | expect(instances.size).to eq(2)
146 | expect(instances.map do |prov|
147 | {
148 | name: prov.get(:name),
149 | component_name: prov.get(:component_name),
150 | value: prov.get(:value)
151 | }
152 | end).to eq(
153 | [
154 | {
155 | name: 'documentumShovel1@/',
156 | component_name: 'shovel',
157 | value: {
158 | 'src-uri' => 'amqp://',
159 | 'src-queue' => 'my-queue',
160 | 'dest-uri' => 'amqp://remote-server',
161 | 'dest-queue' => 'another-queue'
162 | }
163 | },
164 | {
165 | name: 'documentumFederation2@/',
166 | component_name: 'federation',
167 | value: {
168 | 'uri' => 'amqp://',
169 | 'expires' => '360000'
170 | }
171 | }
172 | ]
173 | )
174 | end
175 | end
176 |
177 | describe '#create' do
178 | it 'create parameter' do
179 | provider.expects(:rabbitmqctl).with('set_parameter', '-p', '/', 'shovel', 'documentumShovel',
180 | '{"src-uri":"amqp://","src-queue":"my-queue","dest-uri":"amqp://remote-server","dest-queue":"another-queue"}')
181 | provider.create
182 | end
183 | end
184 |
185 | describe '#destroy' do
186 | it 'destroy parameter' do
187 | provider.expects(:rabbitmqctl).with('clear_parameter', '-p', '/', 'shovel', 'documentumShovel')
188 | provider.destroy
189 | end
190 | end
191 | end
192 |
--------------------------------------------------------------------------------
/spec/unit/puppet/provider/rabbitmq_plugin/rabbitmqctl_spec.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | require 'spec_helper'
4 |
5 | provider_class = Puppet::Type.type(:rabbitmq_plugin).provider(:rabbitmqplugins)
6 | describe provider_class do
7 | let(:resource) do
8 | Puppet::Type::Rabbitmq_plugin.new(
9 | name: 'foo'
10 | )
11 | end
12 | let(:provider) { provider_class.new(resource) }
13 |
14 | it 'calls rabbitmqplugins to enable when node not running' do
15 | provider.class.expects(:rabbitmq_running).returns false
16 | provider.expects(:rabbitmqplugins).with('enable', 'foo')
17 | provider.create
18 | end
19 |
20 | describe '#instances' do
21 | it 'exists' do
22 | expect(provider_class).to respond_to :instances
23 | end
24 |
25 | it 'retrieves instances' do
26 | provider.class.expects(:plugin_list).returns(%w[foo bar])
27 | instances = provider_class.instances
28 | instances_cmp = instances.map { |prov| { name: prov.get(:name) } }
29 | expect(instances_cmp).to eq(
30 | [
31 | { name: 'foo' },
32 | { name: 'bar' }
33 | ]
34 | )
35 | end
36 |
37 | it 'raises error on invalid line' do
38 | provider_class.expects(:plugin_list).returns([' '])
39 | expect { provider_class.instances }.to raise_error Puppet::Error, %r{Cannot parse invalid plugins line}
40 | end
41 | end
42 |
43 | describe '#plugin_list' do
44 | it 'exists' do
45 | expect(provider_class).to respond_to :instances
46 | end
47 |
48 | it 'returns a list of plugins' do
49 | provider.class.expects(:rabbitmqplugins).with('list', '-e', '-m').returns("foo\nbar\nbaz\n")
50 | expect(provider.class.plugin_list).to eq(%w[foo bar baz])
51 | end
52 |
53 | it 'handles no training newline properly' do
54 | provider.class.expects(:rabbitmqplugins).with('list', '-e', '-m').returns("foo\nbar")
55 | expect(provider.class.plugin_list).to eq(%w[foo bar])
56 | end
57 |
58 | it 'handles lines that are not plugins' do
59 | provider.class.expects(:rabbitmqplugins).with('list', '-e', '-m').returns("Listing plugins with pattern \".*\" ...\nfoo\nbar")
60 | expect(provider.class.plugin_list).to eq(%w[foo bar])
61 | end
62 | end
63 |
64 | describe '#exists?' do
65 | it 'matches existing plugins' do
66 | provider_class.expects(:plugin_list).returns(%w[foo])
67 | expect(provider.exists?).to eq(true)
68 | end
69 |
70 | it 'returns false for missing plugins' do
71 | provider_class.expects(:plugin_list).returns(%w[bar])
72 | expect(provider.exists?).to eq(false)
73 | end
74 | end
75 |
76 | context 'with RabbitMQ version >=3.4.0' do
77 | it 'calls rabbitmqplugins to enable' do
78 | provider.class.expects(:rabbitmq_version).returns '3.4.0'
79 | provider.class.expects(:rabbitmq_running).returns true
80 | provider.expects(:rabbitmqplugins).with('enable', 'foo')
81 | provider.create
82 | end
83 |
84 | it 'calls rabbitmqplugins to enable with offline' do
85 | provider.resource[:mode] = :offline
86 | provider.class.expects(:rabbitmq_version).returns '3.4.0'
87 | provider.class.expects(:rabbitmq_running).returns true
88 | provider.expects(:rabbitmqplugins).with('enable', 'foo', '--offline')
89 | provider.create
90 | end
91 |
92 | it 'calls rabbitmqplugins to enable with online' do
93 | provider.resource[:mode] = :online
94 | provider.class.expects(:rabbitmq_version).returns '3.4.0'
95 | provider.class.expects(:rabbitmq_running).returns true
96 | provider.expects(:rabbitmqplugins).with('enable', 'foo', '--online')
97 | provider.create
98 | end
99 |
100 | it 'calls rabbitmqplugins to enable with best' do
101 | provider.resource[:mode] = :best
102 | provider.class.expects(:rabbitmq_version).returns '3.4.0'
103 | provider.class.expects(:rabbitmq_running).returns true
104 | provider.expects(:rabbitmqplugins).with('enable', 'foo')
105 | provider.create
106 | end
107 | end
108 |
109 | context 'with RabbitMQ version < 3.4.0' do
110 | it 'calls rabbitmqplugins to enable' do
111 | provider.class.expects(:rabbitmq_version).returns '3.3.9'
112 | provider.class.expects(:rabbitmq_running).returns true
113 | provider.expects(:rabbitmqplugins).with('enable', 'foo')
114 | provider.create
115 | end
116 |
117 | it 'calls rabbitmqplugins to enable with offline' do
118 | provider.resource[:mode] = :offline
119 | provider.class.expects(:rabbitmq_version).returns '3.3.9'
120 | provider.class.expects(:rabbitmq_running).returns true
121 | provider.expects(:rabbitmqplugins).with('enable', 'foo')
122 | provider.create
123 | end
124 |
125 | it 'calls rabbitmqplugins to enable with online' do
126 | provider.resource[:mode] = :online
127 | provider.class.expects(:rabbitmq_version).returns '3.3.9'
128 | provider.class.expects(:rabbitmq_running).returns true
129 | provider.expects(:rabbitmqplugins).with('enable', 'foo')
130 | provider.create
131 | end
132 |
133 | it 'calls rabbitmqplugins to enable with best' do
134 | provider.resource[:mode] = :best
135 | provider.class.expects(:rabbitmq_version).returns '3.3.9'
136 | provider.class.expects(:rabbitmq_running).returns true
137 | provider.expects(:rabbitmqplugins).with('enable', 'foo')
138 | provider.create
139 | end
140 | end
141 |
142 | it 'calls rabbitmqplugins to disable' do
143 | provider.expects(:rabbitmqplugins).with('disable', 'foo')
144 | provider.destroy
145 | end
146 | end
147 |
--------------------------------------------------------------------------------
/spec/unit/puppet/provider/rabbitmq_policy/rabbitmqctl_spec.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | require 'spec_helper'
4 |
5 | describe Puppet::Type.type(:rabbitmq_policy).provider(:rabbitmqctl) do
6 | let(:resource) do
7 | Puppet::Type.type(:rabbitmq_policy).new(
8 | name: 'ha-all@/',
9 | pattern: '.*',
10 | definition: {
11 | 'ha-mode' => 'all'
12 | }
13 | )
14 | end
15 | let(:provider) { described_class.new(resource) }
16 |
17 | after do
18 | described_class.instance_variable_set(:@policies, nil)
19 | end
20 |
21 | context 'has "@" in policy name' do
22 | let(:resource) do
23 | Puppet::Type.type(:rabbitmq_policy).new(
24 | name: 'ha@home@/',
25 | pattern: '.*',
26 | definition: {
27 | 'ha-mode' => 'all'
28 | },
29 | provider: described_class.name
30 | )
31 | end
32 | let(:provider) { described_class.new(resource) }
33 |
34 | it do
35 | expect(provider.should_policy).to eq('ha@home')
36 | end
37 |
38 | it do
39 | expect(provider.should_vhost).to eq('/')
40 | end
41 | end
42 |
43 | it 'fails with invalid output from list' do
44 | provider.class.expects(:rabbitmqctl_list).with('policies', '-p', '/').returns 'foobar'
45 | provider.class.expects(:rabbitmq_version).returns '3.1.5'
46 | expect { provider.exists? }.to raise_error(Puppet::Error, %r{cannot parse line from list_policies})
47 | end
48 |
49 | context 'with RabbitMQ version >=3.7.0' do
50 | it 'matches policies from list' do
51 | provider.class.expects(:rabbitmq_version).returns '3.7.0'
52 | provider.class.expects(:rabbitmqctl_list).with('policies', '-p', '/').returns <<~EOT
53 | / ha-all .* all {"ha-mode":"all","ha-sync-mode":"automatic"} 0
54 | / test .* exchanges {"ha-mode":"all"} 0
55 | EOT
56 | expect(provider.exists?).to eq(applyto: 'all',
57 | pattern: '.*',
58 | priority: '0',
59 | definition: {
60 | 'ha-mode' => 'all',
61 | 'ha-sync-mode' => 'automatic'
62 | })
63 | end
64 |
65 | it 'matches policies from list targeting quorum queues' do
66 | provider.class.expects(:rabbitmq_version).returns '3.7.0'
67 | provider.class.expects(:rabbitmqctl_list).with('policies', '-p', '/').returns <<~EOT
68 | / ha-all ^.*$ quorum_queues {"delivery-limit":10,"initial-cluster-size":3,"max-length":100000000,"overflow":"reject-publish-dlx"} 0
69 | / test .* exchanges {"ha-mode":"all"} 0
70 | EOT
71 | expect(provider.exists?).to eq(applyto: 'quorum_queues',
72 | pattern: '^.*$',
73 | priority: '0',
74 | definition: {
75 | 'delivery-limit' => 10,
76 | 'initial-cluster-size' => 3,
77 | 'max-length' => 100_000_000,
78 | 'overflow' => 'reject-publish-dlx'
79 | })
80 | end
81 | end
82 |
83 | context 'with RabbitMQ version >=3.2.0 and < 3.7.0' do
84 | it 'matches policies from list' do
85 | provider.class.expects(:rabbitmq_version).returns '3.6.9'
86 | provider.class.expects(:rabbitmqctl_list).with('policies', '-p', '/').returns <<~EOT
87 | / ha-all all .* {"ha-mode":"all","ha-sync-mode":"automatic"} 0
88 | / test exchanges .* {"ha-mode":"all"} 0
89 | EOT
90 | expect(provider.exists?).to eq(applyto: 'all',
91 | pattern: '.*',
92 | priority: '0',
93 | definition: {
94 | 'ha-mode' => 'all',
95 | 'ha-sync-mode' => 'automatic'
96 | })
97 | end
98 | end
99 |
100 | context 'with RabbitMQ version <3.2.0' do
101 | it 'matches policies from list (<3.2.0)' do
102 | provider.class.expects(:rabbitmq_version).returns '3.1.5'
103 | provider.class.expects(:rabbitmqctl_list).with('policies', '-p', '/').returns <<~EOT
104 | / ha-all .* {"ha-mode":"all","ha-sync-mode":"automatic"} 0
105 | / test .* {"ha-mode":"all"} 0
106 | EOT
107 | expect(provider.exists?).to eq(applyto: 'all',
108 | pattern: '.*',
109 | priority: '0',
110 | definition: {
111 | 'ha-mode' => 'all',
112 | 'ha-sync-mode' => 'automatic'
113 | })
114 | end
115 | end
116 |
117 | it 'does not match an empty list' do
118 | provider.class.expects(:rabbitmqctl_list).with('policies', '-p', '/').returns ''
119 | provider.class.expects(:rabbitmq_version).returns '3.1.5'
120 | expect(provider.exists?).to eq(nil)
121 | end
122 |
123 | it 'destroys policy' do
124 | provider.expects(:rabbitmqctl).with('clear_policy', '-p', '/', 'ha-all')
125 | provider.destroy
126 | end
127 |
128 | it 'onlies call set_policy once (<3.2.0)' do
129 | provider.class.expects(:rabbitmq_version).returns '3.1.0'
130 | provider.resource[:priority] = '10'
131 | provider.resource[:applyto] = 'exchanges'
132 | provider.expects(:rabbitmqctl).with('set_policy',
133 | '-p', '/',
134 | 'ha-all',
135 | '.*',
136 | '{"ha-mode":"all"}',
137 | '10').once
138 | provider.priority = '10'
139 | provider.applyto = 'exchanges'
140 | end
141 |
142 | it 'onlies call set_policy once (>=3.2.0)' do
143 | provider.class.expects(:rabbitmq_version).returns '3.2.0'
144 | provider.resource[:priority] = '10'
145 | provider.resource[:applyto] = 'exchanges'
146 | provider.expects(:rabbitmqctl).with('set_policy',
147 | '-p', '/',
148 | '--priority', '10',
149 | '--apply-to', 'exchanges',
150 | 'ha-all',
151 | '.*',
152 | '{"ha-mode":"all"}').once
153 | provider.priority = '10'
154 | provider.applyto = 'exchanges'
155 | end
156 | end
157 |
--------------------------------------------------------------------------------
/spec/unit/puppet/provider/rabbitmq_queue/rabbitmqadmin_spec.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | require 'spec_helper'
4 |
5 | provider_class = Puppet::Type.type(:rabbitmq_queue).provider(:rabbitmqadmin)
6 | describe provider_class do
7 | let(:resource) do
8 | Puppet::Type::Rabbitmq_queue.new(
9 | name: 'test@/',
10 | durable: :true,
11 | auto_delete: :false,
12 | arguments: {}
13 | )
14 | end
15 | let(:provider) { provider_class.new(resource) }
16 |
17 | it 'returns instances' do
18 | provider_class.expects(:rabbitmqctl_list).with('vhosts').returns <<~EOT
19 | /
20 | EOT
21 | provider_class.expects(:rabbitmqctl_list).with('queues', '-p', '/', 'name', 'durable', 'auto_delete', 'arguments').returns <<~EOT
22 | test true false []
23 | 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"}]
24 | EOT
25 | instances = provider_class.instances
26 | expect(instances.size).to eq(2)
27 | end
28 |
29 | it 'calls rabbitmqadmin to create' do
30 | provider.expects(:rabbitmqadmin).with('declare', 'queue', '--vhost=/', '--user=guest', '--password=guest', '-c', '/etc/rabbitmq/rabbitmqadmin.conf', 'name=test', 'durable=true', 'auto_delete=false', 'arguments={}')
31 | provider.create
32 | end
33 |
34 | it 'calls rabbitmqadmin to destroy' do
35 | provider.expects(:rabbitmqadmin).with('delete', 'queue', '--vhost=/', '--user=guest', '--password=guest', '-c', '/etc/rabbitmq/rabbitmqadmin.conf', 'name=test')
36 | provider.destroy
37 | end
38 |
39 | context 'specifying credentials' do
40 | let(:resource) do
41 | Puppet::Type::Rabbitmq_queue.new(
42 | name: 'test@/',
43 | durable: 'true',
44 | auto_delete: 'false',
45 | arguments: {},
46 | user: 'colin',
47 | password: 'secret'
48 | )
49 | end
50 | let(:provider) { provider_class.new(resource) }
51 |
52 | it 'calls rabbitmqadmin to create' do
53 | provider.expects(:rabbitmqadmin).with('declare', 'queue', '--vhost=/', '--user=colin', '--password=secret', '-c', '/etc/rabbitmq/rabbitmqadmin.conf', 'name=test', 'durable=true', 'auto_delete=false', 'arguments={}')
54 | provider.create
55 | end
56 | end
57 | end
58 |
--------------------------------------------------------------------------------
/spec/unit/puppet/provider/rabbitmq_user/rabbitmqctl_spec.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | require 'spec_helper'
4 |
5 | provider_class = Puppet::Type.type(:rabbitmq_user).provider(:rabbitmqctl)
6 | describe provider_class do
7 | let(:resource) do
8 | Puppet::Type.type(:rabbitmq_user).new(
9 | ensure: :present,
10 | name: 'rmq_x',
11 | password: 'secret',
12 | provider: described_class.name
13 | )
14 | end
15 | let(:provider) { provider_class.new(resource) }
16 | let(:instance) { provider.class.instances.first }
17 |
18 | before do
19 | provider.class.stubs(:rabbitmqctl_list).with('users').returns(
20 | "rmq_x [disk, storage]\nrmq_y [network, cpu, administrator]\nrmq_z []\n"
21 | )
22 | end
23 |
24 | describe '#self.instances' do
25 | it { expect(provider.class.instances.size).to eq(3) }
26 |
27 | it 'returns an array of users' do
28 | users = provider.class.instances.map(&:name)
29 | expect(users).to match_array(%w[rmq_x rmq_y rmq_z])
30 | end
31 |
32 | it 'returns the expected tags' do
33 | tags = provider.class.instances.first.get(:tags)
34 | expect(tags).to match_array(%w[disk storage])
35 | end
36 | end
37 |
38 | describe '#exists?' do
39 | it { expect(instance.exists?).to be true }
40 | end
41 |
42 | describe '#create' do
43 | it 'adds a user' do
44 | provider.expects(:rabbitmqctl).with('add_user', 'rmq_x', 'secret')
45 | provider.create
46 | end
47 |
48 | context 'no password supplied' do
49 | let(:resource) do
50 | Puppet::Type.type(:rabbitmq_user).new(
51 | ensure: :present,
52 | name: 'rmq_x'
53 | )
54 | end
55 |
56 | it 'raises an error' do
57 | expect do
58 | provider.create
59 | end.to raise_error(Puppet::Error, 'Password is a required parameter for rabbitmq_user (user: rmq_x)')
60 | end
61 | end
62 | end
63 |
64 | describe '#destroy' do
65 | it 'removes a user' do
66 | provider.expects(:rabbitmqctl).with('delete_user', 'rmq_x')
67 | provider.destroy
68 | end
69 | end
70 |
71 | describe '#check_password' do
72 | context 'correct password' do
73 | before do
74 | provider.class.stubs(:rabbitmqctl).with(
75 | 'eval',
76 | 'rabbit_access_control:check_user_pass_login(list_to_binary("rmq_x"), list_to_binary("secret")).'
77 | ).returns <<~EOT
78 | {ok,{user,<<"rmq_x">>,[],rabbit_auth_backend_internal,
79 | {internal_user,<<"rmq_x">>,
80 | <<193,81,62,182,129,135,196,89,148,87,227,48,86,2,154,
81 | 192,52,119,214,177>>,
82 | []}}}
83 | EOT
84 | end
85 |
86 | it do
87 | provider.check_password('secret')
88 | end
89 | end
90 |
91 | context 'incorrect password' do
92 | before do
93 | provider.class.stubs(:rabbitmqctl).with(
94 | 'eval',
95 | 'rabbit_access_control:check_user_pass_login(list_to_binary("rmq_x"), list_to_binary("nottherightone")).'
96 | ).returns <<~EOT
97 | {refused,"user '~s' - invalid credentials",[<<"rmq_x">>]}
98 | ...done.
99 | EOT
100 | end
101 |
102 | it do
103 | provider.check_password('nottherightone')
104 | end
105 | end
106 | end
107 |
108 | describe '#tags=' do
109 | it 'clears all tags on existing user' do
110 | provider.set(tags: %w[tag1 tag2 tag3])
111 | provider.expects(:rabbitmqctl).with('set_user_tags', 'rmq_x', [])
112 | provider.tags = []
113 | provider.flush
114 | end
115 |
116 | it 'sets multiple tags' do
117 | provider.set(tags: [])
118 | provider.expects(:rabbitmqctl).with('set_user_tags', 'rmq_x', %w[tag1 tag2])
119 | provider.tags = %w[tag1 tag2]
120 | provider.flush
121 | end
122 |
123 | it 'clears tags while keeping admin tag' do
124 | provider.set(tags: %w[administrator tag1 tag2])
125 | resource[:admin] = true
126 | provider.expects(:rabbitmqctl).with('set_user_tags', 'rmq_x', ['administrator'])
127 | provider.tags = []
128 | provider.flush
129 | end
130 |
131 | it 'changes tags while keeping admin tag' do
132 | provider.set(tags: %w[administrator tag1 tag2])
133 | resource[:admin] = true
134 | provider.expects(:rabbitmqctl).with('set_user_tags', 'rmq_x', %w[tag1 tag7 tag3 administrator])
135 | provider.tags = %w[tag1 tag7 tag3]
136 | provider.flush
137 | end
138 | end
139 |
140 | describe '#admin=' do
141 | it 'gets admin value properly' do
142 | provider.set(tags: %w[administrator tag1 tag2])
143 | expect(provider.admin).to be :true
144 | end
145 |
146 | it 'gets false admin value' do
147 | provider.set(tags: %w[tag1 tag2])
148 | expect(provider.admin).to be :false
149 | end
150 |
151 | it 'sets admin value' do
152 | provider.expects(:rabbitmqctl).with('set_user_tags', 'rmq_x', ['administrator'])
153 | resource[:admin] = true
154 | provider.admin = resource[:admin]
155 | provider.flush
156 | end
157 |
158 | it 'adds admin value to existing tags of the user' do
159 | resource[:tags] = %w[tag1 tag2]
160 | provider.expects(:rabbitmqctl).with('set_user_tags', 'rmq_x', %w[tag1 tag2 administrator])
161 | resource[:admin] = true
162 | provider.admin = resource[:admin]
163 | provider.flush
164 | end
165 |
166 | it 'unsets admin value' do
167 | provider.set(tags: ['administrator'])
168 | provider.expects(:rabbitmqctl).with('set_user_tags', 'rmq_x', [])
169 | provider.admin = :false
170 | provider.flush
171 | end
172 |
173 | it 'does not interfere with existing tags on the user when unsetting admin value' do
174 | provider.set(tags: %w[administrator tag1 tag2])
175 | resource[:tags] = %w[tag1 tag2]
176 | provider.expects(:rabbitmqctl).with('set_user_tags', 'rmq_x', %w[tag1 tag2])
177 | provider.admin = :false
178 | provider.flush
179 | end
180 | end
181 | end
182 |
--------------------------------------------------------------------------------
/spec/unit/puppet/provider/rabbitmq_user_permissions/rabbitmqctl_spec.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | require 'spec_helper'
4 |
5 | describe 'Puppet::Type.type(:rabbitmq_user_permissions).provider(:rabbitmqctl)' do
6 | let(:resource) do
7 | Puppet::Type::Rabbitmq_user_permissions.new(
8 | name: 'foo@bar'
9 | )
10 | end
11 | let(:provider_class) { Puppet::Type.type(:rabbitmq_user_permissions).provider(:rabbitmqctl) }
12 | let(:provider) { provider_class.new(resource) }
13 |
14 | after do
15 | provider_class.instance_variable_set(:@users, nil)
16 | end
17 |
18 | it 'matches user permissions from list' do
19 | provider.class.expects(:rabbitmqctl_list).with('user_permissions', 'foo').returns <<~EOT
20 | bar 1 2 3
21 | EOT
22 | expect(provider.exists?).to eq(configure: '1', write: '2', read: '3')
23 | end
24 |
25 | it 'matches user permissions with empty columns' do
26 | provider.class.expects(:rabbitmqctl_list).with('user_permissions', 'foo').returns <<~EOT
27 | bar 3
28 | EOT
29 | expect(provider.exists?).to eq(configure: '', write: '', read: '3')
30 | end
31 |
32 | it 'does not match user permissions with more than 3 columns' do
33 | provider.class.expects(:rabbitmqctl_list).with('user_permissions', 'foo').returns <<~EOT
34 | bar 1 2 3 4
35 | EOT
36 | expect { provider.exists? }.to raise_error(Puppet::Error, %r{cannot parse line from list_user_permissions})
37 | end
38 |
39 | it 'does not match an empty list' do
40 | provider.class.expects(:rabbitmqctl_list).with('user_permissions', 'foo').returns ''
41 | expect(provider.exists?).to eq(nil)
42 | end
43 |
44 | it 'creates default permissions' do
45 | provider.instance_variable_set(:@should_vhost, 'bar')
46 | provider.instance_variable_set(:@should_user, 'foo')
47 | provider.expects(:rabbitmqctl).with('set_permissions', '-p', 'bar', 'foo', "''", "''", "''")
48 | provider.create
49 | end
50 |
51 | it 'destroys permissions' do
52 | provider.instance_variable_set(:@should_vhost, 'bar')
53 | provider.instance_variable_set(:@should_user, 'foo')
54 | provider.expects(:rabbitmqctl).with('clear_permissions', '-p', 'bar', 'foo')
55 | provider.destroy
56 | end
57 |
58 | { configure_permission: '1', write_permission: '2', read_permission: '3' }.each do |k, v|
59 | it "is able to retrieve #{k}" do
60 | provider.class.expects(:rabbitmqctl_list).with('user_permissions', 'foo').returns <<~EOT
61 | bar 1 2 3
62 | EOT
63 | expect(provider.send(k)).to eq(v)
64 | end
65 |
66 | it "is able to retrieve #{k} after exists has been called" do
67 | provider.class.expects(:rabbitmqctl_list).with('user_permissions', 'foo').returns <<~EOT
68 | bar 1 2 3
69 | EOT
70 | provider.exists?
71 | expect(provider.send(k)).to eq(v)
72 | end
73 | end
74 | { configure_permission: %w[foo 2 3],
75 | read_permission: %w[1 2 foo],
76 | write_permission: %w[1 foo 3] }.each do |perm, columns|
77 | it "is able to sync #{perm}" do
78 | provider.class.expects(:rabbitmqctl_list).with('user_permissions', 'foo').returns <<~EOT
79 | bar 1 2 3
80 | EOT
81 | provider.resource[perm] = 'foo'
82 | provider.expects(:rabbitmqctl).with('set_permissions', '-p', 'bar', 'foo', *columns)
83 | provider.send("#{perm}=".to_sym, 'foo')
84 | end
85 | end
86 | it 'onlies call set_permissions once' do
87 | provider.class.expects(:rabbitmqctl_list).with('user_permissions', 'foo').returns <<~EOT
88 | bar 1 2 3
89 | EOT
90 | provider.resource[:configure_permission] = 'foo'
91 | provider.resource[:read_permission] = 'foo'
92 | provider.expects(:rabbitmqctl).with('set_permissions', '-p', 'bar', 'foo', 'foo', '2', 'foo').once
93 | provider.configure_permission = 'foo'
94 | provider.read_permission = 'foo'
95 | end
96 | end
97 |
--------------------------------------------------------------------------------
/spec/unit/puppet/provider/rabbitmq_vhost/rabbitmqctl_spec.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | require 'spec_helper'
4 | describe Puppet::Type.type(:rabbitmq_vhost).provider(:rabbitmqctl) do
5 | let(:resource) do
6 | Puppet::Type::Rabbitmq_vhost.new(
7 | name: 'foo',
8 | description: 'foo description',
9 | default_queue_type: 'quorum',
10 | tags: %w[foo bar]
11 | )
12 | end
13 | let(:provider) { described_class.new(resource) }
14 |
15 | it 'matches vhost names' do
16 | provider.expects(:rabbitmqctl_list).with('vhosts').returns <<~EOT
17 | Listing vhosts ...
18 | foo
19 | ...done.
20 | EOT
21 | expect(provider.exists?).to eq(true)
22 | end
23 |
24 | it 'does not match if no vhosts on system' do
25 | provider.expects(:rabbitmqctl_list).with('vhosts').returns <<~EOT
26 | Listing vhosts ...
27 | ...done.
28 | EOT
29 | expect(provider.exists?).to eq(false)
30 | end
31 |
32 | it 'does not match if no matching vhosts on system' do
33 | provider.expects(:rabbitmqctl_list).with('vhosts').returns <<~EOT
34 | Listing vhosts ...
35 | fooey
36 | ...done.
37 | EOT
38 | expect(provider.exists?).to eq(false)
39 | end
40 |
41 | context 'with RabbitMQ version <3.11.0 (no metadata support)' do
42 | it 'calls rabbitmqctl to create' do
43 | provider.expects(:supports_metadata?).at_least_once.returns false
44 | provider.expects(:rabbitmqctl).with('add_vhost', 'foo')
45 | provider.create
46 | end
47 | end
48 |
49 | context 'with RabbitMQ version >=3.11.0 (metadata support)' do
50 | it 'parses vhost list with valid metadata' do
51 | provider.class.expects(:supports_metadata?).at_least_once.returns true
52 | provider.class.expects(:vhost_list).returns <<~EOT
53 | inventory classic []
54 | / Default virtual host undefined []
55 | search quorum []
56 | testing My cool vhost undefined [tag1, tag2]
57 | EOT
58 | instances = provider.class.instances
59 | expect(instances.size).to eq(4)
60 | expect(instances.map do |prov|
61 | {
62 | name: prov.get(:name),
63 | description: prov.get(:description),
64 | default_queue_type: prov.get(:default_queue_type),
65 | tags: prov.get(:tags)
66 | }
67 | end).to eq(
68 | [
69 | {
70 | name: 'inventory',
71 | description: '',
72 | default_queue_type: 'classic',
73 | tags: []
74 | },
75 | {
76 | name: '/',
77 | description: 'Default virtual host',
78 | default_queue_type: :absent,
79 | tags: []
80 | },
81 | {
82 | name: 'search',
83 | description: '',
84 | default_queue_type: 'quorum',
85 | tags: []
86 | },
87 | {
88 | name: 'testing',
89 | description: 'My cool vhost',
90 | default_queue_type: :absent,
91 | tags: %w[tag1 tag2]
92 | }
93 | ]
94 | )
95 | end
96 |
97 | it 'throws error when parsing invalid vhost metadata' do
98 | provider.class.expects(:supports_metadata?).at_least_once.returns true
99 | provider.class.expects(:vhost_list).returns <<~EOT
100 | inventory undefined []
101 | / Default virtual host undefined
102 | EOT
103 | expect { print provider.class.instances }.to raise_error(Puppet::Error, %r{Cannot parse invalid vhost line: / Default virtual host undefined})
104 | end
105 |
106 | it 'calls rabbitmqctl to create with metadata' do
107 | provider.expects(:supports_metadata?).at_least_once.returns true
108 | provider.expects(:rabbitmqctl).with('add_vhost', 'foo', ['--description', 'foo description'], \
109 | ['--default-queue-type', 'quorum'], ['--tags', 'foo,bar'])
110 | provider.create
111 | end
112 |
113 | it 'updates tags' do
114 | provider.set(tags: %w[tag1 tag2])
115 | provider.expects(:exists?).at_least_once.returns true
116 | provider.expects(:supports_metadata?).at_least_once.returns true
117 | provider.expects(:rabbitmqctl).with('update_vhost_metadata', 'foo', ['--tags', 'tag1,tag2'])
118 | provider.flush
119 | end
120 |
121 | it 'updates description' do
122 | provider.set(description: 'this is the new description')
123 | provider.expects(:exists?).at_least_once.returns true
124 | provider.expects(:supports_metadata?).at_least_once.returns true
125 | provider.expects(:rabbitmqctl).with('update_vhost_metadata', 'foo', ['--description', 'this is the new description'])
126 | provider.flush
127 | end
128 | end
129 |
130 | it 'calls rabbitmqctl to delete' do
131 | provider.expects(:rabbitmqctl).with('delete_vhost', 'foo')
132 | provider.destroy
133 | end
134 | end
135 |
--------------------------------------------------------------------------------
/spec/unit/puppet/type/rabbitmq_binding_spec.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | require 'spec_helper'
4 | describe Puppet::Type.type(:rabbitmq_binding) do
5 | let(:binding) do
6 | Puppet::Type.type(:rabbitmq_binding).new(
7 | name: 'foo@blub@bar',
8 | destination_type: :queue
9 | )
10 | end
11 |
12 | it 'accepts an queue name' do
13 | binding[:name] = 'dan@dude@pl'
14 | expect(binding[:name]).to eq('dan@dude@pl')
15 | end
16 |
17 | it 'requires a name' do
18 | expect do
19 | Puppet::Type.type(:rabbitmq_binding).new({})
20 | end.to raise_error(Puppet::Error, 'Title or name must be provided')
21 | end
22 |
23 | it 'errors when missing source' do
24 | expect do
25 | Puppet::Type.type(:rabbitmq_binding).new(
26 | name: 'test binding',
27 | destination: 'foobar'
28 | )
29 | end.to raise_error(Puppet::Error, %r{`source` must be defined})
30 | end
31 |
32 | it 'errors when missing destination' do
33 | expect do
34 | Puppet::Type.type(:rabbitmq_binding).new(
35 | name: 'test binding',
36 | source: 'foobar'
37 | )
38 | end.to raise_error(Puppet::Error, %r{`destination` must be defined})
39 | end
40 |
41 | it 'accepts an binding destination_type' do
42 | binding[:destination_type] = :exchange
43 | expect(binding[:destination_type]).to eq(:exchange)
44 | end
45 |
46 | it 'accepts a user' do
47 | binding[:user] = :root
48 | expect(binding[:user]).to eq(:root)
49 | end
50 |
51 | it 'accepts a password' do
52 | binding[:password] = :PaSsw0rD
53 | expect(binding[:password]).to eq(:PaSsw0rD)
54 | end
55 | end
56 |
--------------------------------------------------------------------------------
/spec/unit/puppet/type/rabbitmq_cluster_spec.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | require 'spec_helper'
4 | describe Puppet::Type.type(:rabbitmq_cluster) do
5 | let(:rabbitmq_cluster) do
6 | Puppet::Type.type(:rabbitmq_cluster).new(name: 'test_cluster')
7 | end
8 |
9 | it 'accepts a cluster name' do
10 | rabbitmq_cluster[:name] = 'test_cluster'
11 | expect(rabbitmq_cluster[:name]).to eq('test_cluster')
12 | end
13 |
14 | it 'requires a name' do
15 | expect do
16 | Puppet::Type.type(:rabbitmq_cluster).new({})
17 | end.to raise_error(Puppet::Error, 'Title or name must be provided')
18 | end
19 |
20 | it 'check if init_node set to host1' do
21 | rabbitmq_cluster[:init_node] = 'host1'
22 | expect(rabbitmq_cluster[:init_node]).to eq('host1')
23 | end
24 |
25 | it 'check if local_node set to host1' do
26 | rabbitmq_cluster[:local_node] = 'host1'
27 | expect(rabbitmq_cluster[:local_node]).to eq('host1')
28 | end
29 |
30 | it 'local_node not set should default to undef' do
31 | rabbitmq_cluster[:init_node] = 'host1'
32 | expect(rabbitmq_cluster[:local_node]).to eq(:undef)
33 | end
34 |
35 | it 'try to set node_disc_type to ram' do
36 | rabbitmq_cluster[:node_disc_type] = 'ram'
37 | expect(rabbitmq_cluster[:node_disc_type]).to eq('ram')
38 | end
39 |
40 | it 'node_disc_type not set should default to disc' do
41 | rabbitmq_cluster[:name] = 'test_cluster'
42 | expect(rabbitmq_cluster[:node_disc_type]).to eq('disc')
43 | end
44 | end
45 |
--------------------------------------------------------------------------------
/spec/unit/puppet/type/rabbitmq_exchange_spec.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | require 'spec_helper'
4 | describe Puppet::Type.type(:rabbitmq_exchange) do
5 | let(:exchange) do
6 | Puppet::Type.type(:rabbitmq_exchange).new(
7 | name: 'foo@bar',
8 | type: :topic,
9 | internal: false,
10 | auto_delete: false,
11 | durable: true
12 | )
13 | end
14 |
15 | it 'accepts an exchange name' do
16 | exchange[:name] = 'dan@pl'
17 | expect(exchange[:name]).to eq('dan@pl')
18 | end
19 |
20 | it 'requires a name' do
21 | expect do
22 | Puppet::Type.type(:rabbitmq_exchange).new({})
23 | end.to raise_error(Puppet::Error, 'Title or name must be provided')
24 | end
25 |
26 | it 'does not allow whitespace in the name' do
27 | expect do
28 | exchange[:name] = 'b r'
29 | end.to raise_error(Puppet::Error, %r{Valid values match})
30 | end
31 |
32 | it 'does not allow names without @' do
33 | expect do
34 | exchange[:name] = 'b_r'
35 | end.to raise_error(Puppet::Error, %r{Valid values match})
36 | end
37 |
38 | it 'accepts an exchange type' do
39 | exchange[:type] = :direct
40 | expect(exchange[:type]).to eq(:direct)
41 | end
42 |
43 | it 'requires a type' do
44 | expect do
45 | Puppet::Type.type(:rabbitmq_exchange).new(name: 'foo@bar')
46 | end.to raise_error(%r{.*must set type when creating exchange.*})
47 | end
48 |
49 | it 'does not require a type when destroying' do
50 | expect do
51 | Puppet::Type.type(:rabbitmq_exchange).new(name: 'foo@bar', ensure: :absent)
52 | end.not_to raise_error
53 | end
54 |
55 | it 'accepts a user' do
56 | exchange[:user] = :root
57 | expect(exchange[:user]).to eq(:root)
58 | end
59 |
60 | it 'accepts a password' do
61 | exchange[:password] = :PaSsw0rD
62 | expect(exchange[:password]).to eq(:PaSsw0rD)
63 | end
64 | end
65 |
--------------------------------------------------------------------------------
/spec/unit/puppet/type/rabbitmq_parameter_spec.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | require 'spec_helper'
4 | describe Puppet::Type.type(:rabbitmq_parameter) do
5 | let(:parameter) do
6 | Puppet::Type.type(:rabbitmq_parameter).new(
7 | name: 'documentumShovel@/',
8 | component_name: 'shovel',
9 | value: {
10 | 'src-uri' => 'amqp://myremote-server',
11 | 'src-queue' => 'queue.docs.outgoing',
12 | 'dest-uri' => 'amqp://',
13 | 'dest-queue' => 'queue.docs.incoming'
14 | }
15 | )
16 | end
17 |
18 | it 'accepts a valid name' do
19 | parameter[:name] = 'documentumShovel@/'
20 | expect(parameter[:name]).to eq('documentumShovel@/')
21 | end
22 |
23 | it 'requires a name' do
24 | expect do
25 | Puppet::Type.type(:rabbitmq_parameter).new({})
26 | end.to raise_error(Puppet::Error, 'Title or name must be provided')
27 | end
28 |
29 | it 'fails when name does not have a @' do
30 | expect do
31 | parameter[:name] = 'documentumShovel'
32 | end.to raise_error(Puppet::Error, %r{Valid values match})
33 | end
34 |
35 | it 'accepts a string' do
36 | parameter[:component_name] = 'mystring'
37 | expect(parameter[:component_name]).to eq('mystring')
38 | end
39 |
40 | it 'is not empty' do
41 | expect do
42 | parameter[:component_name] = ''
43 | end.to raise_error(Puppet::Error, %r{component_name must be defined})
44 | end
45 |
46 | it 'accepts a valid hash for value' do
47 | parameter[:value] = { 'message-ttl' => '1800000' }
48 | expect(parameter[:value]).to eq({ 'message-ttl' => 1_800_000 })
49 | end
50 |
51 | it 'does not accept an empty string for definition' do
52 | expect do
53 | parameter[:value] = ''
54 | end.to raise_error(Puppet::Error, %r{Invalid value})
55 | end
56 |
57 | it 'does not accept a string for definition' do
58 | expect do
59 | parameter[:value] = 'guest'
60 | end.to raise_error(Puppet::Error, %r{Invalid value})
61 | end
62 |
63 | it 'does not accept an object for definition' do
64 | expect do
65 | parameter[:value] = { 'message-ttl' => Object.new }
66 | end.to raise_error(Puppet::Error, %r{Invalid value})
67 | end
68 |
69 | it 'accepts array as myparameter' do
70 | value = { 'myparameter' => %w[my string] }
71 | parameter[:value] = value
72 | expect(parameter[:value]['myparameter']).to eq(%w[my string])
73 | end
74 |
75 | it 'accepts string as myparameter' do
76 | value = { 'myparameter' => 'mystring' }
77 | parameter[:value] = value
78 | expect(parameter[:value]['myparameter']).to eq('mystring')
79 | end
80 |
81 | it 'converts to integer when string only contains numbers' do
82 | value = { 'myparameter' => '1800000' }
83 | parameter[:value] = value
84 | expect(parameter[:value]['myparameter']).to eq(1_800_000)
85 | end
86 |
87 | context 'autoconvert is set to false' do
88 | let(:parameter) do
89 | Puppet::Type.type(:rabbitmq_parameter).new(
90 | name: 'documentumShovel@/',
91 | component_name: 'shovel',
92 | autoconvert: false,
93 | value: { 'myparameter' => '1800000' }
94 | )
95 | end
96 |
97 | it 'does not convert numeric string to integer' do
98 | expect(parameter[:value]['myparameter']).to eq('1800000')
99 | expect(parameter[:value]['myparameter']).to be_a(String)
100 | end
101 | end
102 | end
103 |
--------------------------------------------------------------------------------
/spec/unit/puppet/type/rabbitmq_plugin_spec.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | require 'spec_helper'
4 | describe Puppet::Type.type(:rabbitmq_plugin) do
5 | let(:plugin) do
6 | Puppet::Type.type(:rabbitmq_plugin).new(name: 'foo')
7 | end
8 |
9 | it 'accepts a plugin name' do
10 | plugin[:name] = 'plugin-name'
11 | expect(plugin[:name]).to eq('plugin-name')
12 | end
13 |
14 | it 'accepts a mode of offline' do
15 | plugin[:mode] = 'offline'
16 | expect(plugin[:mode]).to eq(:offline)
17 | end
18 |
19 | it 'accepts a mode of online' do
20 | plugin[:mode] = 'online'
21 | expect(plugin[:mode]).to eq(:online)
22 | end
23 |
24 | it 'accepts a mode of best' do
25 | plugin[:mode] = 'best'
26 | expect(plugin[:mode]).to eq(:best)
27 | end
28 |
29 | it 'requires a name' do
30 | expect do
31 | Puppet::Type.type(:rabbitmq_plugin).new({})
32 | end.to raise_error(Puppet::Error, 'Title or name must be provided')
33 | end
34 |
35 | it 'defaults to a umask of 0022' do
36 | expect(plugin[:umask]).to eq(0o022)
37 | end
38 |
39 | it 'defaults to a mode of best' do
40 | expect(plugin[:mode]).to eq(:best)
41 | end
42 |
43 | it 'does not allow a non-octal value to be specified' do
44 | expect do
45 | plugin[:umask] = '198'
46 | end.to raise_error(Puppet::Error, %r{The umask specification is invalid: "198"})
47 | end
48 | end
49 |
--------------------------------------------------------------------------------
/spec/unit/puppet/type/rabbitmq_queue_spec.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | require 'spec_helper'
4 | describe Puppet::Type.type(:rabbitmq_queue) do
5 | let(:queue) do
6 | Puppet::Type.type(:rabbitmq_queue).new(
7 | name: 'foo@bar',
8 | durable: :true,
9 | arguments: {
10 | 'x-message-ttl' => 45,
11 | 'x-dead-letter-exchange' => 'deadexchange'
12 | }
13 | )
14 | end
15 |
16 | it 'accepts an queue name' do
17 | queue[:name] = 'dan@pl'
18 | expect(queue[:name]).to eq('dan@pl')
19 | end
20 |
21 | it 'requires a name' do
22 | expect do
23 | Puppet::Type.type(:rabbitmq_queue).new({})
24 | end.to raise_error(Puppet::Error, 'Title or name must be provided')
25 | end
26 |
27 | it 'does not allow whitespace in the name' do
28 | expect do
29 | queue[:name] = 'b r'
30 | end.to raise_error(Puppet::Error, %r{Valid values match})
31 | end
32 |
33 | it 'does not allow names without @' do
34 | expect do
35 | queue[:name] = 'b_r'
36 | end.to raise_error(Puppet::Error, %r{Valid values match})
37 | end
38 |
39 | it 'accepts an arguments with numbers value' do
40 | queue[:arguments] = { 'x-message-ttl' => 30 }
41 | expect(queue[:arguments].to_json).to eq('{"x-message-ttl":30}')
42 | end
43 |
44 | it 'accepts an arguments with string value' do
45 | queue[:arguments] = { 'x-dead-letter-exchange' => 'catchallexchange' }
46 | expect(queue[:arguments].to_json).to eq('{"x-dead-letter-exchange":"catchallexchange"}')
47 | end
48 |
49 | it 'accepts an queue durable' do
50 | queue[:durable] = :true
51 | expect(queue[:durable]).to eq(:true)
52 | end
53 |
54 | it 'accepts a user' do
55 | queue[:user] = :root
56 | expect(queue[:user]).to eq(:root)
57 | end
58 |
59 | it 'accepts a password' do
60 | queue[:password] = :PaSsw0rD
61 | expect(queue[:password]).to eq(:PaSsw0rD)
62 | end
63 | end
64 |
--------------------------------------------------------------------------------
/spec/unit/puppet/type/rabbitmq_user_permissions_spec.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | require 'spec_helper'
4 | describe Puppet::Type.type(:rabbitmq_user_permissions) do
5 | let(:perms) do
6 | Puppet::Type.type(:rabbitmq_user_permissions).new(name: 'foo@bar')
7 | end
8 |
9 | it 'accepts a valid hostname name' do
10 | perms[:name] = 'dan@bar'
11 | expect(perms[:name]).to eq('dan@bar')
12 | end
13 |
14 | it 'requires a name' do
15 | expect do
16 | Puppet::Type.type(:rabbitmq_user_permissions).new({})
17 | end.to raise_error(Puppet::Error, 'Title or name must be provided')
18 | end
19 |
20 | it 'fails when names dont have a @' do
21 | expect do
22 | perms[:name] = 'bar'
23 | end.to raise_error(Puppet::Error, %r{Valid values match})
24 | end
25 |
26 | %i[configure_permission read_permission write_permission].each do |param|
27 | it 'does not default to anything' do
28 | expect(perms[param]).to eq(nil)
29 | end
30 |
31 | it "accepts a valid regex for #{param}" do
32 | perms[param] = '.*?'
33 | expect(perms[param]).to eq('.*?')
34 | end
35 |
36 | it "accepts an empty string for #{param}" do
37 | perms[param] = ''
38 | expect(perms[param]).to eq('')
39 | end
40 |
41 | it "does not accept invalid regex for #{param}" do
42 | expect do
43 | perms[param] = '*'
44 | end.to raise_error(Puppet::Error, %r{Invalid regexp})
45 | end
46 | end
47 | { rabbitmq_vhost: 'dan@test', rabbitmq_user: 'test@dan' }.each do |k, v|
48 | it "autorequires #{k}" do
49 | vhost = if k == :rabbitmq_vhost
50 | Puppet::Type.type(k).new(name: 'test')
51 | else
52 | Puppet::Type.type(k).new(name: 'test', password: 'pass')
53 | end
54 | perm = Puppet::Type.type(:rabbitmq_user_permissions).new(name: v)
55 | Puppet::Resource::Catalog.new :testing do |conf|
56 | [vhost, perm].each { |resource| conf.add_resource resource }
57 | end
58 | rel = perm.autorequire[0]
59 | expect(rel.source.ref).to eq(vhost.ref)
60 | expect(rel.target.ref).to eq(perm.ref)
61 | end
62 | end
63 | end
64 |
--------------------------------------------------------------------------------
/spec/unit/puppet/type/rabbitmq_user_spec.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | require 'spec_helper'
4 | describe Puppet::Type.type(:rabbitmq_user) do
5 | let(:user) do
6 | Puppet::Type.type(:rabbitmq_user).new(name: 'foo', password: 'pass')
7 | end
8 |
9 | it 'accepts a user name' do
10 | user[:name] = 'dan'
11 | expect(user[:name]).to eq('dan')
12 | end
13 |
14 | it 'admin is false when :admin is not set' do
15 | user[:name] = 'dan'
16 | expect(user[:admin]).to eq(:false)
17 | end
18 |
19 | it 'accepts a password' do
20 | user[:password] = 'foo'
21 | expect(user[:password]).to eq('foo')
22 | end
23 |
24 | it 'requires a name' do
25 | expect do
26 | Puppet::Type.type(:rabbitmq_user).new({})
27 | end.to raise_error(Puppet::Error, 'Title or name must be provided')
28 | end
29 |
30 | it 'does not allow whitespace in the name' do
31 | expect do
32 | user[:name] = 'b r'
33 | end.to raise_error(Puppet::Error, %r{Valid values match})
34 | end
35 |
36 | [true, false, 'true', 'false'].each do |val|
37 | it "admin property should accept #{val}" do
38 | user[:admin] = val
39 | expect(user[:admin]).to eq(val.to_s.to_sym)
40 | end
41 | end
42 | it 'does not accept non-boolean values for admin' do
43 | expect do
44 | user[:admin] = 'yes'
45 | end.to raise_error(Puppet::Error, %r{Invalid value})
46 | end
47 |
48 | it 'does not accept tags with spaces' do
49 | expect do
50 | user[:tags] = ['policy maker']
51 | end.to raise_error(Puppet::Error, %r{Invalid tag})
52 | end
53 |
54 | it 'does not accept the administrator tag' do
55 | expect do
56 | user[:tags] = ['administrator']
57 | end.to raise_error(Puppet::Error, %r{must use admin property})
58 | end
59 | end
60 |
--------------------------------------------------------------------------------
/spec/unit/puppet/type/rabbitmq_vhost_spec.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | require 'spec_helper'
4 | describe Puppet::Type.type(:rabbitmq_vhost) do
5 | let(:vhost) do
6 | Puppet::Type.type(:rabbitmq_vhost).new(name: 'foo')
7 | end
8 |
9 | it 'accepts a vhost name' do
10 | vhost[:name] = 'dan'
11 | expect(vhost[:name]).to eq('dan')
12 | end
13 |
14 | it 'requires a name' do
15 | expect do
16 | Puppet::Type.type(:rabbitmq_vhost).new({})
17 | end.to raise_error(Puppet::Error, 'Title or name must be provided')
18 | end
19 |
20 | it 'does not allow whitespace in the name' do
21 | expect do
22 | vhost[:name] = 'b r'
23 | end.to raise_error(Puppet::Error, %r{Valid values match})
24 | end
25 | end
26 |
--------------------------------------------------------------------------------
/templates/README.markdown:
--------------------------------------------------------------------------------
1 | Templates
2 | =========
3 |
4 | Puppet supports templates and templating via ERB, which is part of the Ruby
5 | standard library and is used for many other projects including Ruby on Rails.
6 | Templates allow you to manage the content of template files, for example
7 | configuration files that cannot yet be managed as a Puppet type. Learn more at
8 | http://projects.puppetlabs.com/projects/puppet/wiki/Puppet_Templating
9 |
10 | You can use templates like this:
11 |
12 | class myclass {
13 | package { mypackage: ensure => latest }
14 | service { myservice: ensure => running }
15 | file { "/etc/myfile":
16 | content => template("mymodule/myfile.erb")
17 | }
18 | }
19 |
20 | The templates are searched for in:
21 |
22 | $templatedir/mymodule/myfile.erb
23 | $modulepath/mymodule/templates/myfile.erb
24 |
--------------------------------------------------------------------------------
/templates/enabled_plugins.epp:
--------------------------------------------------------------------------------
1 | % This file managed by Puppet
2 | % Template Path: <%= $rabbitmq::config::module_name %>/templates/enabled_plugins
3 | [<%= ($::rabbitmq::config::_plugins.unique).join(',')%>].
4 |
--------------------------------------------------------------------------------
/templates/inetrc.erb:
--------------------------------------------------------------------------------
1 | %% This file managed by Puppet
2 | %% Template Path: <%= @module_name %>/templates/inetrc
3 | <%- if @ipv6 -%>
4 | {inet6, true}.
5 | <%- end -%>
6 |
--------------------------------------------------------------------------------
/templates/limits.conf:
--------------------------------------------------------------------------------
1 | rabbitmq soft nofile <%= @file_limit %>
2 | rabbitmq hard nofile <%= @file_limit %>
3 |
--------------------------------------------------------------------------------
/templates/rabbitmq-env.conf.epp:
--------------------------------------------------------------------------------
1 | <% $rabbitmq::config::environment_variables.keys.sort.each |$k| { -%>
2 | <%- unless $rabbitmq::config::environment_variables[$k] == Undef {-%>
3 | <%= $k %>=<%= $rabbitmq::config::environment_variables[$k] %>
4 | <%-} -%>
5 | <% } -%>
6 |
--------------------------------------------------------------------------------
/templates/rabbitmqadmin.conf.epp:
--------------------------------------------------------------------------------
1 | [default]
2 | <% if $rabbitmq::config::ssl and $rabbitmq::config::management_ssl {-%>
3 | ssl = True
4 | ssl_ca_cert_file = <%= $rabbitmq::config::ssl_management_cacert %>
5 | ssl_cert_file = <%= $rabbitmq::config::ssl_management_cert %>
6 | ssl_key_file = <%= $rabbitmq::config::ssl_management_key %>
7 | port = <%= $rabbitmq::config::ssl_management_port %>
8 | <% unless $rabbitmq::config::management_hostname {-%>
9 | hostname = <%= $facts['networking']['fqdn'] %>
10 | <% } -%>
11 | <% } else {-%>
12 | port = <%= $rabbitmq::config::management_port %>
13 | <% } -%>
14 | <% if $rabbitmq::config::management_hostname { %>
15 | hostname = <%= $rabbitmq::config::management_hostname %>
16 | <% } -%>
17 |
--------------------------------------------------------------------------------