diff --git a/REFERENCE.md b/REFERENCE.md index 587b674..8267abb 100644 --- a/REFERENCE.md +++ b/REFERENCE.md @@ -1,1759 +1,1810 @@ # Reference ## Table of Contents **Classes** _Public Classes_ * [`rabbitmq`](#rabbitmq): A module to manage RabbitMQ _Private Classes_ * `rabbitmq::config`: Sets all the configuration values for RabbitMQ and creates the directories for config and ssl. * `rabbitmq::install`: Ensures that rabbitmq-server exists * `rabbitmq::install::rabbitmqadmin`: Install rabbitmq admin * `rabbitmq::management`: Manage presence / absence of user resource for guest management user. * `rabbitmq::repo::apt`: requires puppetlabs-apt puppetlabs-stdlib * `rabbitmq::repo::rhel`: Makes sure that the Packagecloud repo is installed * `rabbitmq::service`: This class manages the rabbitmq server service itself. **Resource types** * [`rabbitmq_binding`](#rabbitmq_binding): Native type for managing rabbitmq bindings rabbitmq_binding { 'binding 1': ensure => present, source => 'myexchange' +* [`rabbitmq_cluster`](#rabbitmq_cluster): Type to manage a rabbitmq cluster * [`rabbitmq_erlang_cookie`](#rabbitmq_erlang_cookie): Type to manage the rabbitmq erlang cookie securely This is essentially a private type used by the rabbitmq::config class to manage the erlan * [`rabbitmq_exchange`](#rabbitmq_exchange): Native type for managing rabbitmq exchanges * [`rabbitmq_parameter`](#rabbitmq_parameter): Type for managing rabbitmq parameters * [`rabbitmq_plugin`](#rabbitmq_plugin): manages rabbitmq plugins * [`rabbitmq_policy`](#rabbitmq_policy): Type for managing rabbitmq policies * [`rabbitmq_queue`](#rabbitmq_queue): Native type for managing rabbitmq queue * [`rabbitmq_user`](#rabbitmq_user): Native type for managing rabbitmq users * [`rabbitmq_user_permissions`](#rabbitmq_user_permissions): Type for managing rabbitmq user permissions * [`rabbitmq_vhost`](#rabbitmq_vhost): Native type for managing rabbitmq vhosts ## Classes ### rabbitmq A module to manage RabbitMQ #### Examples ##### Basic usage ```puppet include rabbitmq ``` ##### rabbitmq class ```puppet class { 'rabbitmq': service_manage => false, port => '5672', delete_guest_user => true, } ``` ##### Offline installation from local mirror: ```puppet class { 'rabbitmq': key_content => template('openstack/rabbit.pub.key'), package_gpg_key => '/tmp/rabbit.pub.key', } ``` ##### Use external package key source for any (apt/rpm) package provider: ```puppet class { 'rabbitmq': package_gpg_key => 'http://www.some_site.some_domain/some_key.pub.key', } ``` ##### To use RabbitMQ Environment Variables, use the parameters `environment_variables` e.g.: ```puppet class { 'rabbitmq': port => '5672', environment_variables => { 'NODENAME' => 'node01', 'SERVICENAME' => 'RabbitMQ' } } ``` ##### Change RabbitMQ Config Variables in rabbitmq.config: ```puppet class { 'rabbitmq': port => '5672', config_variables => { 'hipe_compile' => true, 'frame_max' => 131072, 'log_levels' => "[{connection, info}]" } } ``` ##### Change Erlang Kernel Config Variables in rabbitmq.config ```puppet class { 'rabbitmq': port => '5672', config_kernel_variables => { 'inet_dist_listen_min' => 9100, 'inet_dist_listen_max' => 9105, } } ``` ##### Change Management Plugin Config Variables in rabbitmq.config ```puppet class { 'rabbitmq': config_management_variables => { 'rates_mode' => 'basic', } } ``` ##### Change Additional Config Variables in rabbitmq.config ```puppet class { 'rabbitmq': config_additional_variables => { 'autocluster' => '[{consul_service, "rabbit"},{cluster_name, "rabbit"}]', 'foo' => '[{bar, "baz"}]' } } This will result in the following config appended to the config file: {autocluster, [{consul_service, "rabbit"},{cluster_name, "rabbit"}]}, {foo, [{bar, "baz"}]} (This is required for the [autocluster plugin](https://github.com/rabbitmq/rabbitmq-autocluster) ``` ##### Use RabbitMQ clustering facilities ```puppet class { 'rabbitmq': config_cluster => true, cluster_nodes => ['rabbit1', 'rabbit2'], cluster_node_type => 'ram', erlang_cookie => 'A_SECRET_COOKIE_STRING', wipe_db_on_cookie_change => true, } ``` +To create and join the cluster: +```puppet +class { 'rabbitmq': + config_cluster => true, + cluster_nodes => ['rabbit1', 'rabbit2'], + cluster => { + 'name' => 'test_cluster', + 'init_node' => 'hostname' + }, + cluster_node_type => 'ram', + erlang_cookie => 'A_SECRET_COOKIE_STRING', + wipe_db_on_cookie_change => true, +} +``` + #### Parameters The following parameters are available in the `rabbitmq` class. ##### `admin_enable` Data type: `Boolean` If enabled sets up the management interface/plugin for RabbitMQ. This also install the rabbitmqadmin command line tool. Default value: `true` ##### `management_enable` Data type: `Boolean` If enabled sets up the management interface/plugin for RabbitMQ. NOTE: This does not install the rabbitmqadmin command line tool. Default value: `false` ##### `use_config_file_for_plugins` Data type: `Boolean` If enabled the /etc/rabbitmq/enabled_plugins config file is created, replacing the use of the rabbitmqplugins provider to enable plugins. Default value: `false` ##### `auth_backends` Data type: `Optional[Array]` An array specifying authorization/authentication backend to use. Single quotes should be placed around array entries, ex. `['{foo, baz}', 'baz']` Defaults to [rabbit_auth_backend_internal], and if using LDAP defaults to [rabbit_auth_backend_internal, rabbit_auth_backend_ldap]. Default value: `undef` ##### `cluster_node_type` Data type: `Enum['ram', 'disc']` Choose between disc and ram nodes. Default value: 'disc' ##### `cluster_nodes` Data type: `Array` An array of nodes for clustering. Default value: [] ##### `cluster_partition_handling` Data type: `String` Value to set for `cluster_partition_handling` RabbitMQ configuration variable. Default value: 'ignore' +##### `cluster` + +Data type: `Hash` + +If both `name` and `init_node` keys are set then the rabbitmq node is added to +a cluster named after the corresponding key by joining `init_node`. +Note: `init_node` must be included in the [`cluster_nodes`](#cluster_nodes) +parameter. + +Default value: '{}' + ##### `collect_statistics_interval` Data type: `Optional[Integer]` Set the collect_statistics_interval in rabbitmq.config Default value: `undef` ##### `config` Data type: `String` The file to use as the rabbitmq.config template. Default value: 'rabbitmq/rabbitmq.config.erb' ##### `config_additional_variables` Data type: `Hash` Additional config variables in rabbitmq.config Default value: {} ##### `config_cluster` Data type: `Boolean` Enable or disable clustering support. Default value: `false` ##### `config_kernel_variables` Data type: `Hash` Hash of Erlang kernel configuration variables to set (see [Variables Configurable in rabbitmq.config](#variables-configurable-in-rabbitmq.config)). Default value: {} ##### `config_path` Data type: `Stdlib::Absolutepath` The path to write the RabbitMQ configuration file to. Default value: '/etc/rabbitmq/rabbitmq.config' ##### `config_ranch` Data type: `Boolean` When true, suppress config directives needed for older (<3.6) RabbitMQ versions. Default value: `true` ##### `config_management_variables` Data type: `Hash` Hash of configuration variables for the [Management Plugin](https://www.rabbitmq.com/management.html). Default value: {} ##### `config_stomp` Data type: `Boolean` Enable or disable stomp. Default value: `false` ##### `config_shovel` Data type: `Boolean` Enable or disable shovel. Default value: `false` ##### `config_shovel_statics` Data type: `Hash` Hash of static shovel configurations Default value: {} ##### `config_variables` Data type: `Hash` To set config variables in rabbitmq.config Default value: {} ##### `default_user` Data type: `String` Username to set for the `default_user` in rabbitmq.config. Default value: 'guest' ##### `default_pass` Data type: `String` Password to set for the `default_user` in rabbitmq.config. Default value: 'guest' ##### `delete_guest_user` Data type: `Boolean` Controls whether default guest user is deleted. Default value: `false` ##### `env_config` Data type: `String` The template file to use for rabbitmq_env.config. Default value: 'rabbitmq/rabbitmq-env.conf.erb' ##### `env_config_path` Data type: `Stdlib::Absolutepath` The path to write the rabbitmq_env.config file to. Default value: '/etc/rabbitmq/rabbitmq-env.conf' ##### `environment_variables` Data type: `Hash` RabbitMQ Environment Variables in rabbitmq_env.config Default value: { 'LC_ALL' => 'en_US.UTF-8' } ##### `erlang_cookie` Data type: `Optional[String]` The erlang cookie to use for clustering - must be the same between all nodes. This value has no default and must be set explicitly if using clustering. If you run Pacemaker and you don't want to use RabbitMQ buildin cluster, you can set config_cluster to 'False' and set 'erlang_cookie'. Default value: `undef` ##### `file_limit` Data type: `Variant[Integer[-1],Enum['unlimited'],Pattern[/^(infinity|\d+(:(infinity|\d+))?)$/]]` Set rabbitmq file ulimit. Defaults to 16384. Only available on systems with `$::osfamily == 'Debian'` or `$::osfamily == 'RedHat'`. Default value: 16384 ##### `heartbeat` Data type: `Optional[Integer]` Set the heartbeat timeout interval, default is unset which uses the builtin server defaults of 60 seconds. Setting this Default value: `undef` ##### `inetrc_config` Data type: `String` Template to use for the inetrc config Default value: 'rabbitmq/inetrc.erb' ##### `inetrc_config_path` Data type: `Stdlib::Absolutepath` Path of the file to push the inetrc config to. Default value: '/etc/rabbitmq/inetrc' ##### `ipv6` Data type: `Boolean` Whether to listen on ipv6 Default value: `false` ##### `interface` Data type: `Optional[String]` Interface to bind to (sets tcp_listeners parameter). By default, bind to all interfaces to `0` will disable heartbeats. Default value: `undef` ##### `key_content` Data type: `Optional[String]` Uses content method for Debian OS family. Should be a template for apt::source class. Overrides `package_gpg_key` behavior, if enabled. Undefined by default. Default value: `undef` ##### `ldap_auth` Data type: `Boolean` Set to true to enable LDAP auth. Default value: `false` ##### `ldap_server` Data type: `Variant[String[1],Array[String[1]]]` LDAP server or servers to use for auth. Default value: 'ldap' ##### `ldap_user_dn_pattern` Data type: `Optional[String]` User DN pattern for LDAP auth. Default value: `undef` ##### `ldap_other_bind` Data type: `String` How to bind to the LDAP server. Defaults to 'anon'. Default value: 'anon' ##### `ldap_config_variables` Data type: `Hash` Hash of other LDAP config variables. Default value: {} ##### `ldap_use_ssl` Data type: `Boolean` Set to true to use SSL for the LDAP server. Default value: `false` ##### `ldap_port` Data type: `Integer[1, 65535]` Numeric port for LDAP server. Default value: 389 ##### `ldap_log` Data type: `Boolean` Set to true to log LDAP auth. Default value: `false` ##### `manage_python` Data type: `Boolean` If enabled, on platforms that don't provide a Python 2 package by default, ensure that the python package is installed (for rabbitmqadmin). This will only apply if `admin_enable` and `service_manage` are set. Default value: `true` ##### `management_hostname` Data type: `Optional[String]` The hostname for the RabbitMQ management interface. Default value: `undef` ##### `management_port` Data type: `Integer[1, 65535]` The port for the RabbitMQ management interface. Default value: 15672 ##### `management_ip_address` Data type: `Optional[String]` Allows you to set the IP for management interface to bind to separately. Set to 127.0.0.1 to bind to localhost only, or 0.0.0.0 to bind to all interfaces. Default value: `undef` ##### `management_ssl` Data type: `Boolean` Enable/Disable SSL for the management port. Has an effect only if ssl => true. Default value: `true` ##### `node_ip_address` Data type: `Optional[String]` Allows you to set the IP for RabbitMQ service to bind to. Set to 127.0.0.1 to bind to localhost only, or 0.0.0.0 to bind to all interfaces. Default value: `undef` ##### `package_apt_pin` Data type: `Optional[Variant[Numeric, String]]` Whether to pin the package to a particular source Default value: `undef` ##### `package_ensure` Data type: `String` Determines the ensure state of the package. Set to installed by default, but could be changed to latest. Default value: 'installed' ##### `package_gpg_key` Data type: `Optional[String]` RPM package GPG key to import. Uses source method. Should be a URL for Debian/RedHat OS family, or a file name for RedHat OS family. Set to https://www.rabbitmq.com/rabbitmq-release-signing-key.asc for RedHat OS Family and https://packagecloud.io/rabbitmq/rabbitmq-server/gpgkey for Debian OS Family by default. Note, that `key_content`, if specified, would override this parameter for Debian OS family. Default value: `undef` ##### `package_name` Data type: `Variant[String, Array]` Name(s) of the package(s) to install Default value: 'rabbitmq' ##### `port` Data type: `Integer` The RabbitMQ port. Default value: 5672 ##### `python_package` Data type: `String` Name of the package required by rabbitmqadmin. Default value: 'python' ##### `repos_ensure` Data type: `Boolean` Ensure that a repo with the official (and newer) RabbitMQ package is configured, along with its signing key. Defaults to false (use system packages). This does not ensure that soft dependencies (like EPEL on RHEL systems) are present. It also does not solve the erlang dependency. See https://www.rabbitmq.com/which-erlang.html for a good breakdown of the different ways of handling the erlang deps. See also https://github.com/voxpupuli/puppet-rabbitmq/issues/788 Default value: `false` ##### `service_ensure` Data type: `Enum['running', 'stopped']` The state of the service. Default value: 'running' ##### `service_manage` Data type: `Boolean` Determines if the service is managed. Default value: `true` ##### `service_name` Data type: `String` The name of the service to manage. Default value: 'rabbitmq' ##### `service_restart` Data type: `Boolean` Default defined in param.pp. Whether to restart the service on config change. Default value: `true` ##### `ssl` Data type: `Boolean` Configures the service for using SSL. Default value: `false` ##### `ssl_cacert` Data type: `Optional[Stdlib::Absolutepath]` CA cert path to use for SSL. Default value: `undef` ##### `ssl_cert` Data type: `Optional[Stdlib::Absolutepath]` Cert to use for SSL. Default value: `undef` ##### `ssl_cert_password` Data type: `Optional[String]` Password used when generating CSR. Default value: `undef` ##### `ssl_depth` Data type: `Optional[Integer]` SSL verification depth. Default value: `undef` ##### `ssl_dhfile` Data type: `Optional[Stdlib::Absolutepath]` Use this dhparam file [example: generate with `openssl dhparam -out /etc/rabbitmq/ssl/dhparam.pem 2048` Default value: `undef` ##### `ssl_erl_dist` Data type: `Boolean` Whether to use the erlang package's SSL (relies on the ssl_erl_path fact) Default value: `false` ##### `ssl_honor_cipher_order` Data type: `Boolean` Force use of server cipher order Default value: `true` ##### `ssl_interface` Data type: `Optional[String]` Interface for SSL listener to bind to Default value: `undef` ##### `ssl_key` Data type: `Optional[Stdlib::Absolutepath]` Key to use for SSL. Default value: `undef` ##### `ssl_only` Data type: `Boolean` Configures the service to only use SSL. No cleartext TCP listeners will be created. Requires that ssl => true and port => undef Default value: `false` ##### `ssl_management_port` Data type: `Integer[1, 65535]` SSL management port. Default value: 15671 ##### `ssl_management_cacert` Data type: `Optional[Stdlib::Absolutepath]` SSL management cacert. If unset set to ssl_cacert for backwards compatibility. Default value: $ssl_cacert ##### `ssl_management_cert` Data type: `Optional[Stdlib::Absolutepath]` SSL management cert. If unset set to ssl_cert for backwards compatibility. Default value: $ssl_cert ##### `ssl_management_key` Data type: `Optional[Stdlib::Absolutepath]` SSL management key. If unset set to ssl_key for backwards compatibility. Default value: $ssl_key ##### `ssl_port` Data type: `Integer[1, 65535]` SSL port for RabbitMQ Default value: 5671 ##### `ssl_reuse_sessions` Data type: `Boolean` Reuse ssl sessions Default value: `true` ##### `ssl_secure_renegotiate` Data type: `Boolean` Use ssl secure renegotiate Default value: `true` ##### `ssl_stomp_port` Data type: `Integer[1, 65535]` SSL stomp port. Default value: 6164 ##### `ssl_verify` Data type: `Enum['verify_none','verify_peer']` rabbitmq.config SSL verify setting. Default value: 'verify_none' ##### `ssl_fail_if_no_peer_cert` Data type: `Boolean` rabbitmq.config `fail_if_no_peer_cert` setting. Default value: `false` ##### `ssl_management_verify` Data type: `Enum['verify_none','verify_peer']` rabbitmq.config SSL verify setting for rabbitmq_management. Default value: 'verify_none' ##### `ssl_versions` Data type: `Optional[Array]` Choose which SSL versions to enable. Example: `['tlsv1.2', 'tlsv1.1']` Note that it is recommended to disable `sslv3 and `tlsv1` to prevent against POODLE and BEAST attacks. Please see the [RabbitMQ SSL](https://www.rabbitmq.com/ssl.html) documentation for more information. Default value: `undef` ##### `ssl_ciphers` Data type: `Array` Support only a given list of SSL ciphers, using either the Erlang or OpenSSL styles. Supported ciphers in your install can be listed with: `rabbitmqctl eval 'ssl:cipher_suites().'` Functionality can be tested with cipherscan or similar tool: https://github.com/mozilla/cipherscan * Erlang style: `['ecdhe_rsa,aes_256_cbc,sha', 'dhe_rsa,aes_256_cbc,sha']` * OpenSSL style: `['ECDHE-RSA-AES256-SHA', 'DHE-RSA-AES256-SHA']` Default value: [] ##### `ssl_crl_check` Data type: `Enum['true','false','peer','best_effort']` Perform CRL (Certificate Revocation List) verification Please see the [Erlang SSL](https://erlang.org/doc/man/ssl.html#type-crl_check) module documentation for more information. Default value: 'false' ##### `ssl_crl_cache_hash_dir` Data type: `Optional[Stdlib::Absolutepath]` This setting makes use of a directory where CRLs are stored in files named by the hash of the issuer name. Please see the [Erlang SSL](https://erlang.org/doc/man/ssl.html#type-crl_cache_opts) module documentation for more information. Default value: `undef` ##### `ssl_crl_cache_http_timeout` Data type: `Optional[Integer]` This setting enables use of internal CRLs cache and sets HTTP timeout interval on fetching CRLs from distributino URLs defined inside certificate. Please see the [Erlang SSL](https://erlang.org/doc/man/ssl.html#type-crl_cache_opts) module documentation for more information. Default value: `undef` ##### `stomp_port` Data type: `Integer[1, 65535]` The port to use for Stomp. Default value: 6163 ##### `stomp_ssl_only` Data type: `Boolean` Configures STOMP to only use SSL. No cleartext STOMP TCP listeners will be created. Requires setting ssl_stomp_port also. Default value: `false` ##### `stomp_ensure` Data type: `Boolean` Enable to install the stomp plugin. Default value: `false` ##### `tcp_backlog` Data type: `Integer` The size of the backlog on TCP connections. Default value: 128 ##### `tcp_keepalive` Data type: `Boolean` Enable TCP connection keepalive for RabbitMQ service. Default value: `false` ##### `tcp_recbuf` Data type: `Optional[Integer]` Corresponds to recbuf in RabbitMQ `tcp_listen_options` Default value: `undef` ##### `tcp_sndbuf` Data type: `Optional[Integer]` Integer, corresponds to sndbuf in RabbitMQ `tcp_listen_options` Default value: `undef` ##### `wipe_db_on_cookie_change` Data type: `Boolean` Boolean to determine if we should DESTROY AND DELETE the RabbitMQ database. Default value: `false` ##### `rabbitmq_user` Data type: `String` OS dependent The system user the rabbitmq daemon runs as. Default value: 'rabbitmq' ##### `rabbitmq_group` Data type: `String` OS dependent The system group the rabbitmq daemon runs as. Default value: 'rabbitmq' ##### `rabbitmq_home` Data type: `Stdlib::Absolutepath` OS dependent The home directory of the rabbitmq deamon. Default value: '/var/lib/rabbitmq' ##### `rabbitmqadmin_package` Data type: `Optional[String]` OS dependent If undef: install rabbitmqadmin via archive, otherwise via package Default value: `undef` ##### `archive_options` Data type: `Array` Extra options to Archive resource to download rabbitmqadmin file Default value: [] ##### `loopback_users` Data type: `Array` This option configures a list of users to allow access via the loopback interfaces Default value: ['guest'] ##### `package_source` Data type: `Optional[String]` Default value: `undef` ##### `package_provider` Data type: `Optional[String]` Default value: `undef` ##### `ssl_management_fail_if_no_peer_cert` Data type: `Boolean` Default value: `false` ## Resource types ### rabbitmq_binding Native type for managing rabbitmq bindings rabbitmq_binding { 'binding 1': ensure => present, source => 'myexchange', destination => 'myqueue', vhost => 'myvhost', user => 'dan', password => 'bar', destination_type => 'queue', routing_key => 'key1', arguments => {}, } rabbitmq_binding { 'binding 2': ensure => present, source => 'myexchange', destination => 'myqueue', vhost => 'myvhost', user => 'dan', password => 'bar', destination_type => 'queue', routing_key => 'key2', arguments => {}, } #### Examples ##### Create a rabbitmq_binding ```puppet rabbitmq_binding { 'myexchange@myqueue@myvhost': user => 'dan', password => 'bar', destination_type => 'queue', routing_key => '#', arguments => {}, ensure => present, } ``` ##### Create bindings with same source / destination / vhost but different routing key using individual parameters ```puppet ``` #### Properties The following properties are available in the `rabbitmq_binding` type. ##### `ensure` Valid values: present, absent The basic property that the resource should be in. Default value: present ##### `source` Valid values: %r{^\S+$} namevar source of binding ##### `destination` Valid values: %r{^\S+$} namevar destination of binding ##### `vhost` Valid values: %r{^\S+$} namevar vhost Default value: / ##### `routing_key` Valid values: %r{^\S*$} namevar binding routing_key ##### `destination_type` Valid values: %r{queue|exchange} binding destination_type Default value: queue ##### `arguments` binding arguments #### Parameters The following parameters are available in the `rabbitmq_binding` type. ##### `name` namevar resource name, either source@destination@vhost or arbitrary name with params ##### `user` Valid values: %r{^\S+$} The user to use to connect to rabbitmq Default value: guest ##### `password` Valid values: %r{\S+} The password to use to connect to rabbitmq Default value: guest +### rabbitmq_cluster + +Type to manage a rabbitmq cluster + +#### Properties + +The following properties are available in the `rabbitmq_cluster` type. + +#### `init_node` + +Data type: `String` + +The node to join to initiate the cluster. It is mandatory. + +Default value: unset + +#### `node_disc_type` + +Data type: `Enum['ram', 'disc']` + +Choose between disc and ram cluster nodes. + +Default value: disc + ### rabbitmq_erlang_cookie Type to manage the rabbitmq erlang cookie securely This is essentially a private type used by the rabbitmq::config class to manage the erlang cookie. It replaces the rabbitmq_erlang_cookie fact from earlier versions of this module. It manages the content of the cookie usually located at "${rabbitmq_home}/.erlang.cookie", which includes stopping the rabbitmq service and wiping out the database at "${rabbitmq_home}/mnesia" if the user agrees to it. We don't recommend using this type directly. #### Properties The following properties are available in the `rabbitmq_erlang_cookie` type. ##### `content` Valid values: %r{^\S+$} Content of cookie #### Parameters The following parameters are available in the `rabbitmq_erlang_cookie` type. ##### `path` ##### `force` Valid values: `true`, `false` Default value: `false` ##### `rabbitmq_user` Default value: rabbitmq ##### `rabbitmq_group` Default value: rabbitmq ##### `rabbitmq_home` Default value: /var/lib/rabbitmq ##### `service_name` Valid values: %r{^\S+$} ### rabbitmq_exchange Native type for managing rabbitmq exchanges #### Examples ##### Create a rabbitmq_exchange ```puppet rabbitmq_exchange { 'myexchange@myvhost': user => 'dan', password => 'bar', type => 'topic', ensure => present, internal => false, auto_delete => false, durable => true, arguments => { hash-header => 'message-distribution-hash' } } ``` #### Properties The following properties are available in the `rabbitmq_exchange` type. ##### `ensure` Valid values: present, absent The basic property that the resource should be in. Default value: present #### Parameters The following parameters are available in the `rabbitmq_exchange` type. ##### `name` Valid values: %r{^\S*@\S+$} namevar Name of exchange ##### `type` Valid values: %r{^\S+$} Exchange type to be set *on creation* ##### `durable` Valid values: %r{^\S+$} Exchange durability to be set *on creation* Default value: `false` ##### `auto_delete` Valid values: %r{^\S+$} Exchange auto delete option to be set *on creation* Default value: `false` ##### `internal` Valid values: %r{^\S+$} Exchange internal option to be set *on creation* Default value: `false` ##### `arguments` Exchange arguments example: {"hash-header": "message-distribution-hash"} ##### `user` Valid values: %r{^\S+$} The user to use to connect to rabbitmq Default value: guest ##### `password` Valid values: %r{\S+} The password to use to connect to rabbitmq Default value: guest ### rabbitmq_parameter Type for managing rabbitmq parameters #### Examples ##### Create some rabbitmq_parameter resources ```puppet rabbitmq_parameter { 'documentumShovel@/': component_name => '', value => { 'src-uri' => 'amqp://', 'src-queue' => 'my-queue', 'dest-uri' => 'amqp://remote-server', 'dest-queue' => 'another-queue', }, } rabbitmq_parameter { 'documentumFed@/': component_name => 'federation-upstream', value => { 'uri' => 'amqp://myserver', 'expires' => '360000', }, } rabbitmq_parameter { 'documentumShovelNoMunging@/': component_name => '', value => { 'src-uri' => 'amqp://', 'src-exchange' => 'my-exchange', 'src-exchange-key' => '6', 'src-queue' => 'my-queue', 'dest-uri' => 'amqp://remote-server', 'dest-exchange' => 'another-exchange', }, autoconvert => false, } ``` #### Properties The following properties are available in the `rabbitmq_parameter` type. ##### `ensure` Valid values: present, absent The basic property that the resource should be in. Default value: present ##### `component_name` The component_name to use when setting parameter, eg: shovel or federation ##### `value` A hash of values to use with the component name you are setting #### Parameters The following parameters are available in the `rabbitmq_parameter` type. ##### `name` Valid values: %r{^\S+@\S+$} namevar combination of name@vhost to set parameter for ##### `autoconvert` Valid values: `true`, `false` whether numeric strings from `value` should be converted to int automatically Default value: `true` ### rabbitmq_plugin manages rabbitmq plugins #### Examples ##### query all currently enabled plugins ```puppet $ puppet resource rabbitmq_plugin ``` ##### Ensure a rabbitmq_plugin resource ```puppet rabbitmq_plugin {'rabbitmq_stomp': ensure => present, } ``` ##### Ensure a rabbitmq_plugin offline resource (with RabbitMQ version >=3.4.0) ```puppet rabbitmq_plugin {'rabbitmq_stomp': ensure => present, mode => 'offline', } ``` #### Properties The following properties are available in the `rabbitmq_plugin` type. ##### `ensure` Valid values: present, absent The basic property that the resource should be in. Default value: present #### Parameters The following parameters are available in the `rabbitmq_plugin` type. ##### `name` Valid values: %r{^\S+$} namevar The name of the plugin to enable ##### `mode` Valid values: online, offline, best Define how the plugin should be enabled regarding node status. Default value: best ##### `umask` Sets the octal umask to be used while creating this resource Default value: 0022 ### rabbitmq_policy Type for managing rabbitmq policies #### Examples ##### Create a rabbitmq_policy ```puppet rabbitmq_policy { 'ha-all@myvhost': pattern => '.*', priority => 0, applyto => 'all', definition => { 'ha-mode' => 'all', 'ha-sync-mode' => 'automatic', }, } ``` #### Properties The following properties are available in the `rabbitmq_policy` type. ##### `ensure` Valid values: present, absent The basic property that the resource should be in. Default value: present ##### `pattern` policy pattern ##### `applyto` Valid values: all, exchanges, queues policy apply to Default value: all ##### `definition` policy definition ##### `priority` Valid values: %r{^\d+$} policy priority Default value: 0 #### Parameters The following parameters are available in the `rabbitmq_policy` type. ##### `name` Valid values: %r{^\S+@\S+$} namevar combination of policy@vhost to create policy for ### rabbitmq_queue Native type for managing rabbitmq queue #### Examples ##### Create a rabbitmq_queue ```puppet rabbitmq_queue { 'myqueue@myvhost': ensure => present, user => 'dan', password => 'bar', durable => true, auto_delete => false, arguments => { x-message-ttl => 123, x-dead-letter-exchange => 'other' }, } ``` #### Properties The following properties are available in the `rabbitmq_queue` type. ##### `ensure` Valid values: present, absent The basic property that the resource should be in. Default value: present #### Parameters The following parameters are available in the `rabbitmq_queue` type. ##### `name` Valid values: %r{^\S*@\S+$} namevar Name of queue ##### `durable` Valid values: %r{true|false} Queue is durable Default value: `true` ##### `auto_delete` Valid values: %r{true|false} Queue will be auto deleted Default value: `false` ##### `arguments` Queue arguments example: {x-message-ttl => 60, x-expires => 10} ##### `user` Valid values: %r{^\S+$} The user to use to connect to rabbitmq Default value: guest ##### `password` Valid values: %r{\S+} The password to use to connect to rabbitmq Default value: guest ### rabbitmq_user Native type for managing rabbitmq users #### Examples ##### query all current users ```puppet $ puppet resource rabbitmq_user ``` ##### Configure a user, dan ```puppet rabbitmq_user { 'dan': admin => true, password => 'bar', } ``` ##### Optional parameter tags will set further rabbitmq tags like monitoring, policymaker, etc. ```puppet To set the administrator tag use admin-flag. rabbitmq_user { 'dan': admin => true, password => 'bar', tags => ['monitoring', 'tag1'], } ``` #### Properties The following properties are available in the `rabbitmq_user` type. ##### `ensure` Valid values: present, absent The basic property that the resource should be in. Default value: present ##### `password` User password to be set *on creation* and validated each run ##### `admin` Valid values: %r{true|false} whether or not user should be an admin Default value: false ##### `tags` additional tags for the user Default value: [] #### Parameters The following parameters are available in the `rabbitmq_user` type. ##### `name` Valid values: %r{^\S+$} namevar Name of user ### rabbitmq_user_permissions Type for managing rabbitmq user permissions #### Examples ##### Define some rabbitmq_user_permissions ```puppet rabbitmq_user_permissions { 'dan@myvhost': configure_permission => '.*', read_permission => '.*', write_permission => '.*', } ``` #### Properties The following properties are available in the `rabbitmq_user_permissions` type. ##### `ensure` Valid values: present, absent The basic property that the resource should be in. Default value: present ##### `configure_permission` regexp representing configuration permissions ##### `read_permission` regexp representing read permissions ##### `write_permission` regexp representing write permissions #### Parameters The following parameters are available in the `rabbitmq_user_permissions` type. ##### `name` Valid values: %r{^\S+@\S+$} namevar combination of user@vhost to grant privileges to ### rabbitmq_vhost Native type for managing rabbitmq vhosts #### Examples ##### query all current vhosts ```puppet $ puppet resource rabbitmq_vhost` ``` ##### Create a rabbitmq_vhost ```puppet rabbitmq_vhost { 'myvhost': ensure => present, } ``` #### Properties The following properties are available in the `rabbitmq_vhost` type. ##### `ensure` Valid values: present, absent The basic property that the resource should be in. Default value: present #### Parameters The following parameters are available in the `rabbitmq_vhost` type. ##### `name` Valid values: %r{^\S+$} namevar The name of the vhost to add diff --git a/data/common.yaml b/data/common.yaml index ce9887f..f130e56 100644 --- a/data/common.yaml +++ b/data/common.yaml @@ -1,99 +1,100 @@ --- rabbitmq::admin_enable: true rabbitmq::management_enable: false rabbitmq::use_config_file_for_plugins: false +rabbitmq::cluster: {} rabbitmq::cluster_node_type: 'disc' rabbitmq::cluster_nodes: [] rabbitmq::config: 'rabbitmq/rabbitmq.config.erb' rabbitmq::config_cluster: false rabbitmq::config_path: '/etc/rabbitmq/rabbitmq.config' rabbitmq::config_ranch: true rabbitmq::config_stomp: false rabbitmq::config_shovel: false rabbitmq::config_shovel_statics: {} rabbitmq::default_user: 'guest' rabbitmq::default_pass: 'guest' rabbitmq::delete_guest_user: false rabbitmq::env_config: 'rabbitmq/rabbitmq-env.conf.erb' rabbitmq::env_config_path: '/etc/rabbitmq/rabbitmq-env.conf' rabbitmq::erlang_cookie: ~ rabbitmq::interface: ~ rabbitmq::management_ip_address: ~ rabbitmq::management_port: 15672 rabbitmq::management_ssl: true rabbitmq::management_hostname: ~ rabbitmq::node_ip_address: ~ rabbitmq::package_apt_pin: ~ rabbitmq::package_ensure: 'installed' rabbitmq::package_gpg_key: ~ rabbitmq::package_name: 'rabbitmq' rabbitmq::package_source: ~ rabbitmq::package_provider: ~ rabbitmq::repos_ensure: false rabbitmq::manage_python: true rabbitmq::python_package: 'python' rabbitmq::rabbitmq_user: 'rabbitmq' rabbitmq::rabbitmq_group: 'rabbitmq' rabbitmq::rabbitmq_home: '/var/lib/rabbitmq' rabbitmq::port: 5672 rabbitmq::tcp_keepalive: false rabbitmq::tcp_backlog: 128 rabbitmq::tcp_sndbuf: ~ rabbitmq::tcp_recbuf: ~ rabbitmq::heartbeat: ~ rabbitmq::service_ensure: 'running' rabbitmq::service_manage: true rabbitmq::service_name: 'rabbitmq' rabbitmq::ssl: false rabbitmq::ssl_only: false rabbitmq::ssl_cacert: ~ rabbitmq::ssl_cert: ~ rabbitmq::ssl_key: ~ rabbitmq::ssl_depth: ~ rabbitmq::ssl_cert_password: ~ rabbitmq::ssl_port: 5671 rabbitmq::ssl_interface: ~ rabbitmq::ssl_management_port: 15671 rabbitmq::ssl_stomp_port: 6164 rabbitmq::ssl_verify: 'verify_none' rabbitmq::ssl_fail_if_no_peer_cert: false rabbitmq::ssl_management_verify: 'verify_none' rabbitmq::ssl_management_fail_if_no_peer_cert: false rabbitmq::ssl_versions: ~ rabbitmq::ssl_secure_renegotiate: true rabbitmq::ssl_reuse_sessions: true rabbitmq::ssl_honor_cipher_order: true rabbitmq::ssl_dhfile: ~ rabbitmq::ssl_ciphers: [] rabbitmq::stomp_ensure: false rabbitmq::ldap_auth: false rabbitmq::ldap_server: 'ldap' rabbitmq::ldap_user_dn_pattern: ~ rabbitmq::ldap_other_bind: 'anon' rabbitmq::ldap_use_ssl: false rabbitmq::ldap_port: 389 rabbitmq::ldap_log: false rabbitmq::ldap_config_variables: {} rabbitmq::stomp_port: 6163 rabbitmq::stomp_ssl_only: false rabbitmq::wipe_db_on_cookie_change: false rabbitmq::cluster_partition_handling: 'ignore' rabbitmq::file_limit: 16384 rabbitmq::environment_variables: 'LC_ALL': 'en_US.UTF-8' rabbitmq::config_variables: {} rabbitmq::config_kernel_variables: {} rabbitmq::config_management_variables: {} rabbitmq::config_additional_variables: {} rabbitmq::auth_backends: ~ rabbitmq::key_content: ~ rabbitmq::collect_statistics_interval: ~ rabbitmq::ipv6: false rabbitmq::inetrc_config: 'rabbitmq/inetrc.erb' rabbitmq::inetrc_config_path: '/etc/rabbitmq/inetrc' rabbitmq::ssl_erl_dist: false rabbitmq::rabbitmqadmin_package: ~ rabbitmq::archive_options: [] rabbitmq::loopback_users: - 'guest' rabbitmq::service_restart: true diff --git a/examples/cluster/join_cluster_and_change_name.pp b/examples/cluster/join_cluster_and_change_name.pp new file mode 100644 index 0000000..7b1dda4 --- /dev/null +++ b/examples/cluster/join_cluster_and_change_name.pp @@ -0,0 +1,5 @@ +# This sets the cluster name to `test_cluster` +# If run on another host than host1, this will join the host1's cluster +rabbitmq_cluster { 'test_cluster': + init_node => 'host1', +} diff --git a/lib/facter/rabbitmq_clustername.rb b/lib/facter/rabbitmq_clustername.rb new file mode 100644 index 0000000..7a178df --- /dev/null +++ b/lib/facter/rabbitmq_clustername.rb @@ -0,0 +1,15 @@ +Facter.add(:rabbitmq_clustername) do + setcode do + if Facter::Util::Resolution.which('rabbitmqctl') + ret = nil + cluster_status = Facter::Core::Execution.execute('rabbitmqctl -q cluster_status 2>&1') + [%r!{cluster_name,<<"(\S+)">>}!, %r!^Cluster name: (\S+)$!].each do |r| + if (data = r.match(cluster_status)) + ret = data[1] + break + end + end + end + ret + end +end diff --git a/lib/puppet/provider/rabbitmq_cluster/rabbitmqctl.rb b/lib/puppet/provider/rabbitmq_cluster/rabbitmqctl.rb new file mode 100644 index 0000000..f65326d --- /dev/null +++ b/lib/puppet/provider/rabbitmq_cluster/rabbitmqctl.rb @@ -0,0 +1,40 @@ +require File.expand_path(File.join(File.dirname(__FILE__), '..', 'rabbitmq_cli')) +Puppet::Type.type(:rabbitmq_cluster).provide( + :rabbitmqctl, + parent: Puppet::Provider::RabbitmqCli +) do + confine feature: :posix + + def exists? + cluster_name == @resource[:name].to_s + end + + def create + storage_type = @resource[:node_disc_type].to_s + + init_node = @resource[:init_node].to_s.gsub(%r{^.*@}, '') + + if [Facter.value(:hostname), Facter.value(:fqdn)].include? init_node + return rabbitmqctl('set_cluster_name', @resource[:name]) unless cluster_name == resource[:name].to_s + else + rabbitmqctl('stop_app') + rabbitmqctl('join_cluster', "rabbit@#{init_node}", "--#{storage_type}") + rabbitmqctl('start_app') + end + end + + def destroy + rabbitmqctl('stop_app') + rabbitmqctl('reset') + rabbitmqctl('start_app') + end + + def cluster_name + cluster_status = rabbitmqctl('-q', 'cluster_status') + [%r!{cluster_name,<<"(\S+)">>}!, %r!^Cluster name: (\S+)$!].each do |r| + if (data = r.match(cluster_status)) + return data[1] + end + end + end +end diff --git a/lib/puppet/type/rabbitmq_cluster.rb b/lib/puppet/type/rabbitmq_cluster.rb new file mode 100644 index 0000000..f481065 --- /dev/null +++ b/lib/puppet/type/rabbitmq_cluster.rb @@ -0,0 +1,50 @@ +Puppet::Type.newtype(:rabbitmq_cluster) do + desc <<-DESC +Native type for managing rabbitmq cluster + +@example Configure a cluster, rabbit_cluster + rabbitmq_cluster { 'rabbit_cluster': + init_node => 'host1' + } + +@example Optional parameter tags will set further rabbitmq tags like monitoring, policymaker, etc. + To set the cluster name use cluster_name. + rabbitmq_cluster { 'rabbit_cluster': + init_node => 'host1', + node_disc_type => 'ram', + } +DESC + + ensurable do + defaultto(:present) + newvalue(:present) do + provider.create + end + newvalue(:absent) do + provider.destroy + end + end + + autorequire(:service) { 'rabbitmq-server' } + + newparam(:name, namevar: true) do + desc 'The cluster name' + end + + newparam(:init_node) do + desc 'Name of which cluster node to join.' + validate do |value| + resource.validate_init_node(value) + end + end + + newparam(:node_disc_type) do + desc 'Storage type of node, default disc.' + newvalues(%r{disc|ram}) + defaultto('disc') + end + + def validate_init_node(value) + raise ArgumentError, 'init_node must be defined' if value.empty? + end +end diff --git a/manifests/init.pp b/manifests/init.pp index 71097b9..12a7198 100644 --- a/manifests/init.pp +++ b/manifests/init.pp @@ -1,539 +1,554 @@ # # @summary A module to manage RabbitMQ # # @example Basic usage # include rabbitmq # # @example rabbitmq class # class { 'rabbitmq': # service_manage => false, # port => '5672', # delete_guest_user => true, # } # # @example Offline installation from local mirror: # class { 'rabbitmq': # key_content => template('openstack/rabbit.pub.key'), # package_gpg_key => '/tmp/rabbit.pub.key', # } # # @example Use external package key source for any (apt/rpm) package provider: # class { 'rabbitmq': # package_gpg_key => 'http://www.some_site.some_domain/some_key.pub.key', # } # # @example To use RabbitMQ Environment Variables, use the parameters `environment_variables` e.g.: # class { 'rabbitmq': # port => '5672', # environment_variables => { # 'NODENAME' => 'node01', # 'SERVICENAME' => 'RabbitMQ' # } # } # # @example Change RabbitMQ Config Variables in rabbitmq.config: # class { 'rabbitmq': # port => '5672', # config_variables => { # 'hipe_compile' => true, # 'frame_max' => 131072, # 'log_levels' => "[{connection, info}]" # } # } # # @example Change Erlang Kernel Config Variables in rabbitmq.config # class { 'rabbitmq': # port => '5672', # config_kernel_variables => { # 'inet_dist_listen_min' => 9100, # 'inet_dist_listen_max' => 9105, # } # } # # @example Change Management Plugin Config Variables in rabbitmq.config # class { 'rabbitmq': # config_management_variables => { # 'rates_mode' => 'basic', # } # } # # @example Change Additional Config Variables in rabbitmq.config # class { 'rabbitmq': # config_additional_variables => { # 'autocluster' => '[{consul_service, "rabbit"},{cluster_name, "rabbit"}]', # 'foo' => '[{bar, "baz"}]' # } # } # # This will result in the following config appended to the config file: # {autocluster, [{consul_service, "rabbit"},{cluster_name, "rabbit"}]}, # {foo, [{bar, "baz"}]} # (This is required for the [autocluster plugin](https://github.com/rabbitmq/rabbitmq-autocluster) # # @example Use RabbitMQ clustering facilities # class { 'rabbitmq': +# cluster => { +# 'name' => 'test_cluster', +# 'init_node' => 'hostname' +# }, # config_cluster => true, # cluster_nodes => ['rabbit1', 'rabbit2'], # cluster_node_type => 'ram', # erlang_cookie => 'A_SECRET_COOKIE_STRING', # wipe_db_on_cookie_change => true, # } # # @param admin_enable # If enabled sets up the management interface/plugin for RabbitMQ. # This also install the rabbitmqadmin command line tool. # @param management_enable # If enabled sets up the management interface/plugin for RabbitMQ. # NOTE: This does not install the rabbitmqadmin command line tool. # @param use_config_file_for_plugins # If enabled the /etc/rabbitmq/enabled_plugins config file is created, # replacing the use of the rabbitmqplugins provider to enable plugins. # @param auth_backends # An array specifying authorization/authentication backend to use. Single quotes should be placed around array entries, # ex. `['{foo, baz}', 'baz']` Defaults to [rabbit_auth_backend_internal], and if using LDAP defaults to [rabbit_auth_backend_internal, # rabbit_auth_backend_ldap]. +# @param cluster Join cluster and change name of cluster. # @param cluster_node_type # Choose between disc and ram nodes. # @param cluster_nodes # An array of nodes for clustering. # @param cluster_partition_handling # Value to set for `cluster_partition_handling` RabbitMQ configuration variable. # @param collect_statistics_interval # Set the collect_statistics_interval in rabbitmq.config # @param config # The file to use as the rabbitmq.config template. # @param config_additional_variables # Additional config variables in rabbitmq.config # @param config_cluster # Enable or disable clustering support. # @param config_kernel_variables # Hash of Erlang kernel configuration variables to set (see [Variables Configurable in rabbitmq.config](#variables-configurable-in-rabbitmq.config)). # @param config_path # The path to write the RabbitMQ configuration file to. # @param config_ranch # When true, suppress config directives needed for older (<3.6) RabbitMQ versions. # @param config_management_variables # Hash of configuration variables for the [Management Plugin](https://www.rabbitmq.com/management.html). # @param config_stomp # Enable or disable stomp. # @param config_shovel # Enable or disable shovel. # @param config_shovel_statics # Hash of static shovel configurations # @param config_variables # To set config variables in rabbitmq.config # @param default_user # Username to set for the `default_user` in rabbitmq.config. # @param default_pass # Password to set for the `default_user` in rabbitmq.config. # @param delete_guest_user # Controls whether default guest user is deleted. # @param env_config # The template file to use for rabbitmq_env.config. # @param env_config_path # The path to write the rabbitmq_env.config file to. # @param environment_variables # RabbitMQ Environment Variables in rabbitmq_env.config # @param erlang_cookie # The erlang cookie to use for clustering - must be the same between all nodes. This value has no default and must be # set explicitly if using clustering. If you run Pacemaker and you don't want to use RabbitMQ buildin cluster, you can set config_cluster # to 'False' and set 'erlang_cookie'. # @param file_limit # Set rabbitmq file ulimit. Defaults to 16384. Only available on systems with `$::osfamily == 'Debian'` or `$::osfamily == 'RedHat'`. # @param oom_score_adj # Set rabbitmq-server process OOM score. Defaults to 0. # @param heartbeat # Set the heartbeat timeout interval, default is unset which uses the builtin server defaults of 60 seconds. Setting this # @param inetrc_config # Template to use for the inetrc config # @param inetrc_config_path # Path of the file to push the inetrc config to. # @param ipv6 # Whether to listen on ipv6 # @param interface # Interface to bind to (sets tcp_listeners parameter). By default, bind to all interfaces # to `0` will disable heartbeats. # @param key_content # Uses content method for Debian OS family. Should be a template for apt::source class. Overrides `package_gpg_key` # behavior, if enabled. Undefined by default. # @param ldap_auth # Set to true to enable LDAP auth. # @param ldap_server # LDAP server or servers to use for auth. # @param ldap_user_dn_pattern # User DN pattern for LDAP auth. # @param ldap_other_bind # How to bind to the LDAP server. Defaults to 'anon'. # @param ldap_config_variables # Hash of other LDAP config variables. # @param ldap_use_ssl # Set to true to use SSL for the LDAP server. # @param ldap_port # Numeric port for LDAP server. # @param ldap_log # Set to true to log LDAP auth. # @param manage_python # If enabled, on platforms that don't provide a Python 2 package by default, ensure that the python package is # installed (for rabbitmqadmin). This will only apply if `admin_enable` and `service_manage` are set. # @param management_hostname # The hostname for the RabbitMQ management interface. # @param management_port # The port for the RabbitMQ management interface. # @param management_ip_address # Allows you to set the IP for management interface to bind to separately. Set to 127.0.0.1 to bind to # localhost only, or 0.0.0.0 to bind to all interfaces. # @param management_ssl # Enable/Disable SSL for the management port. Has an effect only if ssl => true. # @param node_ip_address # Allows you to set the IP for RabbitMQ service to bind to. Set to 127.0.0.1 to bind to localhost only, or 0.0.0.0 # to bind to all interfaces. # @param package_apt_pin # Whether to pin the package to a particular source # @param package_ensure # Determines the ensure state of the package. Set to installed by default, but could be changed to latest. # @param package_gpg_key # RPM package GPG key to import. Uses source method. Should be a URL for Debian/RedHat OS family, or a file name for # RedHat OS family. Set to https://www.rabbitmq.com/rabbitmq-release-signing-key.asc for RedHat OS Family and # https://packagecloud.io/rabbitmq/rabbitmq-server/gpgkey for Debian OS Family by default. Note, that `key_content`, if specified, would # override this parameter for Debian OS family. # @param package_name # Name(s) of the package(s) to install # @param port # The RabbitMQ port. # @param python_package # Name of the package required by rabbitmqadmin. # @param repos_ensure # Ensure that a repo with the official (and newer) RabbitMQ package is configured, along with its signing key. # Defaults to false (use system packages). This does not ensure that soft dependencies (like EPEL on RHEL systems) are present. # It also does not solve the erlang dependency. See https://www.rabbitmq.com/which-erlang.html for a good breakdown of the # different ways of handling the erlang deps. See also https://github.com/voxpupuli/puppet-rabbitmq/issues/788 # @param service_ensure # The state of the service. # @param service_manage # Determines if the service is managed. # @param service_name # The name of the service to manage. # @param service_restart # Default defined in param.pp. Whether to restart the service on config change. # @param ssl # Configures the service for using SSL. # @param ssl_cacert # CA cert path to use for SSL. # @param ssl_cert # Cert to use for SSL. # @param ssl_cert_password # Password used when generating CSR. # @param ssl_depth # SSL verification depth. # @param ssl_dhfile # Use this dhparam file [example: generate with `openssl dhparam -out /etc/rabbitmq/ssl/dhparam.pem 2048` # @param ssl_erl_dist # Whether to use the erlang package's SSL (relies on the ssl_erl_path fact) # @param ssl_honor_cipher_order # Force use of server cipher order # @param ssl_interface # Interface for SSL listener to bind to # @param ssl_key # Key to use for SSL. # @param ssl_only # Configures the service to only use SSL. No cleartext TCP listeners will be created. Requires that ssl => true and # port => undef # @param ssl_management_port # SSL management port. # @param ssl_management_cacert # SSL management cacert. If unset set to ssl_cacert for backwards compatibility. # @param ssl_management_cert # SSL management cert. If unset set to ssl_cert for backwards compatibility. # @param ssl_management_key # SSL management key. If unset set to ssl_key for backwards compatibility. # @param ssl_port # SSL port for RabbitMQ # @param ssl_reuse_sessions # Reuse ssl sessions # @param ssl_secure_renegotiate # Use ssl secure renegotiate # @param ssl_stomp_port # SSL stomp port. # @param ssl_verify # rabbitmq.config SSL verify setting. # @param ssl_fail_if_no_peer_cert # rabbitmq.config `fail_if_no_peer_cert` setting. # @param ssl_management_verify # rabbitmq.config SSL verify setting for rabbitmq_management. # @param ssl_versions # Choose which SSL versions to enable. Example: `['tlsv1.2', 'tlsv1.1']` Note # that it is recommended to disable `sslv3 and `tlsv1` to prevent against # POODLE and BEAST attacks. Please see the # [RabbitMQ SSL](https://www.rabbitmq.com/ssl.html) documentation for more information. # @param ssl_ciphers # Support only a given list of SSL ciphers, using either the Erlang or OpenSSL styles. # Supported ciphers in your install can be listed with: `rabbitmqctl eval 'ssl:cipher_suites().'` # Functionality can be tested with cipherscan or similar tool: https://github.com/mozilla/cipherscan # * Erlang style: `['ecdhe_rsa,aes_256_cbc,sha', 'dhe_rsa,aes_256_cbc,sha']` # * OpenSSL style: `['ECDHE-RSA-AES256-SHA', 'DHE-RSA-AES256-SHA']` # @param ssl_crl_check # Perform CRL (Certificate Revocation List) verification # Please see the [Erlang SSL](https://erlang.org/doc/man/ssl.html#type-crl_check) module documentation for more information. # @param ssl_crl_cache_hash_dir # This setting makes use of a directory where CRLs are stored in files named by the hash of the issuer name. # Please see the [Erlang SSL](https://erlang.org/doc/man/ssl.html#type-crl_cache_opts) module documentation for more information. # @param ssl_crl_cache_http_timeout # This setting enables use of internal CRLs cache and sets HTTP timeout interval on fetching CRLs from distributino URLs defined inside certificate. # Please see the [Erlang SSL](https://erlang.org/doc/man/ssl.html#type-crl_cache_opts) module documentation for more information. # @param stomp_port # The port to use for Stomp. # @param stomp_ssl_only # Configures STOMP to only use SSL. No cleartext STOMP TCP listeners will be created. Requires setting ssl_stomp_port also. # @param stomp_ensure # Enable to install the stomp plugin. # @param tcp_backlog # The size of the backlog on TCP connections. # @param tcp_keepalive # Enable TCP connection keepalive for RabbitMQ service. # @param tcp_recbuf # Corresponds to recbuf in RabbitMQ `tcp_listen_options` # @param tcp_sndbuf # Integer, corresponds to sndbuf in RabbitMQ `tcp_listen_options` # @param wipe_db_on_cookie_change # Boolean to determine if we should DESTROY AND DELETE the RabbitMQ database. # @param rabbitmq_user # OS dependent The system user the rabbitmq daemon runs as. # @param rabbitmq_group # OS dependent The system group the rabbitmq daemon runs as. # @param rabbitmq_home # OS dependent The home directory of the rabbitmq deamon. # @param rabbitmqadmin_package # OS dependent If undef: install rabbitmqadmin via archive, otherwise via package # @param archive_options # Extra options to Archive resource to download rabbitmqadmin file # @param loopback_users # This option configures a list of users to allow access via the loopback interfaces # class rabbitmq ( Boolean $admin_enable = true, Boolean $management_enable = false, Boolean $use_config_file_for_plugins = false, + Hash $cluster = $rabbitmq::cluster, Enum['ram', 'disc'] $cluster_node_type = 'disc', Array $cluster_nodes = [], String $config = 'rabbitmq/rabbitmq.config.erb', Boolean $config_cluster = false, Stdlib::Absolutepath $config_path = '/etc/rabbitmq/rabbitmq.config', Boolean $config_ranch = true, Boolean $config_stomp = false, Boolean $config_shovel = false, Hash $config_shovel_statics = {}, String $default_user = 'guest', String $default_pass = 'guest', Boolean $delete_guest_user = false, String $env_config = 'rabbitmq/rabbitmq-env.conf.erb', Stdlib::Absolutepath $env_config_path = '/etc/rabbitmq/rabbitmq-env.conf', Optional[String] $erlang_cookie = undef, Optional[String] $interface = undef, Optional[String] $management_ip_address = undef, Integer[1, 65535] $management_port = 15672, Boolean $management_ssl = true, Optional[String] $management_hostname = undef, Optional[String] $node_ip_address = undef, Optional[Variant[Numeric, String]] $package_apt_pin = undef, String $package_ensure = 'installed', Optional[String] $package_gpg_key = undef, Variant[String, Array] $package_name = 'rabbitmq', Optional[String] $package_source = undef, Optional[String] $package_provider = undef, Boolean $repos_ensure = false, Boolean $manage_python = true, String $python_package = 'python', String $rabbitmq_user = 'rabbitmq', String $rabbitmq_group = 'rabbitmq', Stdlib::Absolutepath $rabbitmq_home = '/var/lib/rabbitmq', Integer $port = 5672, Boolean $tcp_keepalive = false, Integer $tcp_backlog = 128, Optional[Integer] $tcp_sndbuf = undef, Optional[Integer] $tcp_recbuf = undef, Optional[Integer] $heartbeat = undef, Enum['running', 'stopped'] $service_ensure = 'running', Boolean $service_manage = true, String $service_name = 'rabbitmq', Boolean $ssl = false, Boolean $ssl_only = false, Optional[Stdlib::Absolutepath] $ssl_cacert = undef, Optional[Stdlib::Absolutepath] $ssl_cert = undef, Optional[Stdlib::Absolutepath] $ssl_key = undef, Optional[Integer] $ssl_depth = undef, Optional[String] $ssl_cert_password = undef, Integer[1, 65535] $ssl_port = 5671, Optional[String] $ssl_interface = undef, Integer[1, 65535] $ssl_management_port = 15671, Optional[Stdlib::Absolutepath] $ssl_management_cacert = $ssl_cacert, Optional[Stdlib::Absolutepath] $ssl_management_cert = $ssl_cert, Optional[Stdlib::Absolutepath] $ssl_management_key = $ssl_key, Integer[1, 65535] $ssl_stomp_port = 6164, Enum['verify_none','verify_peer'] $ssl_verify = 'verify_none', Boolean $ssl_fail_if_no_peer_cert = false, Enum['verify_none','verify_peer'] $ssl_management_verify = 'verify_none', Boolean $ssl_management_fail_if_no_peer_cert = false, Optional[Array] $ssl_versions = undef, Boolean $ssl_secure_renegotiate = true, Boolean $ssl_reuse_sessions = true, Boolean $ssl_honor_cipher_order = true, Optional[Stdlib::Absolutepath] $ssl_dhfile = undef, Array $ssl_ciphers = [], Enum['true','false','peer','best_effort'] $ssl_crl_check = 'false', Optional[Stdlib::Absolutepath] $ssl_crl_cache_hash_dir = undef, Optional[Integer] $ssl_crl_cache_http_timeout = undef, Boolean $stomp_ensure = false, Boolean $ldap_auth = false, Variant[String[1],Array[String[1]]] $ldap_server = 'ldap', Optional[String] $ldap_user_dn_pattern = undef, String $ldap_other_bind = 'anon', Boolean $ldap_use_ssl = false, Integer[1, 65535] $ldap_port = 389, Boolean $ldap_log = false, Hash $ldap_config_variables = {}, Integer[1, 65535] $stomp_port = 6163, Boolean $stomp_ssl_only = false, Boolean $wipe_db_on_cookie_change = false, String $cluster_partition_handling = 'ignore', Variant[Integer[-1],Enum['unlimited'],Pattern[/^(infinity|\d+(:(infinity|\d+))?)$/]] $file_limit = 16384, Integer[-1000, 1000] $oom_score_adj = 0, Hash $environment_variables = { 'LC_ALL' => 'en_US.UTF-8' }, Hash $config_variables = {}, Hash $config_kernel_variables = {}, Hash $config_management_variables = {}, Hash $config_additional_variables = {}, Optional[Array] $auth_backends = undef, Optional[String] $key_content = undef, Optional[Integer] $collect_statistics_interval = undef, Boolean $ipv6 = false, String $inetrc_config = 'rabbitmq/inetrc.erb', Stdlib::Absolutepath $inetrc_config_path = '/etc/rabbitmq/inetrc', Boolean $ssl_erl_dist = false, Optional[String] $rabbitmqadmin_package = undef, Array $archive_options = [], Array $loopback_users = ['guest'], Boolean $service_restart = true, ) { if $ssl_only and ! $ssl { fail('$ssl_only => true requires that $ssl => true') } if $config_stomp and $stomp_ssl_only and ! $ssl_stomp_port { fail('$stomp_ssl_only requires that $ssl_stomp_port be set') } if $ssl_versions { unless $ssl { fail('$ssl_versions requires that $ssl => true') } } if $ssl_crl_check != 'false' { unless $ssl { fail('$ssl_crl_check requires that $ssl => true') } } if $ssl_crl_cache_hash_dir { unless $ssl { fail('$ssl_crl_cache_hash_dir requires that $ssl => true') } if $ssl_crl_check == 'false' { fail('$ssl_crl_cache_http_timeout requires that $ssl_crl_check => true|peer|best_effort') } } if $ssl_crl_cache_http_timeout { unless $ssl { fail('$ssl_crl_cache_http_timeout requires that $ssl => true') } if $ssl_crl_check == 'false' { fail('$ssl_crl_cache_http_timeout requires that $ssl_crl_check => true|peer|best_effort') } } if $repos_ensure { case $facts['os']['family'] { 'RedHat': { contain rabbitmq::repo::rhel Class['rabbitmq::repo::rhel'] -> Class['rabbitmq::install'] } 'Debian': { contain rabbitmq::repo::apt Class['rabbitmq::repo::apt'] -> Class['rabbitmq::install'] } default: { } } } contain rabbitmq::install contain rabbitmq::config contain rabbitmq::service contain rabbitmq::management unless $use_config_file_for_plugins { # NOTE(hjensas): condition on $service_manage to keep current behaviour. # The condition is likely not required because installiton of rabbitmqadmin # is no longer handled here. # TODO: Remove the condition on $service_manage if ($management_enable or $admin_enable) and $service_manage { rabbitmq_plugin { 'rabbitmq_management': ensure => present, notify => Class['rabbitmq::service'], provider => 'rabbitmqplugins', } } if ($stomp_ensure) { rabbitmq_plugin { 'rabbitmq_stomp': ensure => present, notify => Class['rabbitmq::service'], provider => 'rabbitmqplugins', } } if ($ldap_auth) { rabbitmq_plugin { 'rabbitmq_auth_backend_ldap': ensure => present, notify => Class['rabbitmq::service'], provider => 'rabbitmqplugins', } } if ($config_shovel) { rabbitmq_plugin { 'rabbitmq_shovel': ensure => present, notify => Class['rabbitmq::service'], provider => 'rabbitmqplugins', } if ($management_enable or $admin_enable) { rabbitmq_plugin { 'rabbitmq_shovel_management': ensure => present, notify => Class['rabbitmq::service'], provider => 'rabbitmqplugins', } } } } if $admin_enable and $service_manage { include 'rabbitmq::install::rabbitmqadmin' Class['rabbitmq::service'] -> Class['rabbitmq::install::rabbitmqadmin'] Class['rabbitmq::install::rabbitmqadmin'] -> Rabbitmq_exchange<| |> } + if $config_cluster and $cluster['name'] and $cluster['init_node'] { + create_resources('rabbitmq_cluster', { + $cluster['name'] => { + 'init_node' => $cluster['init_node'], + 'node_disc_type' => $cluster_node_type, + } + }) + } + if ($service_restart) { Class['rabbitmq::config'] ~> Class['rabbitmq::service'] } Class['rabbitmq::install'] -> Class['rabbitmq::config'] -> Class['rabbitmq::service'] -> Class['rabbitmq::management'] # Make sure the various providers have their requirements in place. - Class['rabbitmq::install'] -> Rabbitmq_plugin<| |> + Class['rabbitmq::install'] -> Rabbitmq_plugin<| |> -> Rabbitmq_cluster<| |> } diff --git a/spec/acceptance/clustering_spec.rb b/spec/acceptance/clustering_spec.rb index 204eef0..6349929 100644 --- a/spec/acceptance/clustering_spec.rb +++ b/spec/acceptance/clustering_spec.rb @@ -1,59 +1,75 @@ require 'spec_helper_acceptance' describe 'rabbitmq clustering' do context 'rabbitmq::wipe_db_on_cookie_change => false' do it 'runs successfully' do pp = <<-EOS class { 'rabbitmq': + cluster => { 'name' => 'rabbit_cluster', 'init_node' => $facts['fqdn'] }, config_cluster => true, cluster_nodes => ['rabbit1', 'rabbit2'], cluster_node_type => 'ram', + environment_variables => { 'RABBITMQ_USE_LONGNAME' => true }, erlang_cookie => 'TESTCOOKIE', wipe_db_on_cookie_change => false, } if $facts['os']['family'] == 'RedHat' { class { 'erlang': epel_enable => true} Class['erlang'] -> Class['rabbitmq'] } EOS apply_manifest(pp, expect_failures: true) end describe file('/var/lib/rabbitmq/.erlang.cookie') do it { is_expected.not_to contain 'TESTCOOKIE' } end end context 'rabbitmq::wipe_db_on_cookie_change => true' do it 'runs successfully' do pp = <<-EOS class { 'rabbitmq': + cluster => { 'name' => 'rabbit_cluster', 'init_node' => $facts['fqdn'] }, config_cluster => true, cluster_nodes => ['rabbit1', 'rabbit2'], cluster_node_type => 'ram', + environment_variables => { 'RABBITMQ_USE_LONGNAME' => true }, erlang_cookie => 'TESTCOOKIE', wipe_db_on_cookie_change => true, } if $facts['os']['family'] == 'RedHat' { class { 'erlang': epel_enable => true} Class['erlang'] -> Class['rabbitmq'] } EOS apply_manifest(pp, catch_failures: true) end describe file('/etc/rabbitmq/rabbitmq.config') do it { is_expected.to be_file } it { is_expected.to contain 'cluster_nodes' } it { is_expected.to contain 'rabbit@rabbit1' } it { is_expected.to contain 'rabbit@rabbit2' } it { is_expected.to contain 'ram' } end describe file('/var/lib/rabbitmq/.erlang.cookie') do it { is_expected.to be_file } it { is_expected.to contain 'TESTCOOKIE' } end + + describe 'rabbitmq_cluster' do + context 'cluster_name => rabbit_cluster' do + it 'cluster has name' do + shell('rabbitmqctl -q cluster_status') do |r| + expect(r.stdout).to match(%r!({cluster_name,<<"rabbit_cluster">>}|^Cluster name: rabbit_cluster$)!) + expect(r.exit_code).to be_zero + end + # rubocop:enable RSpec/MultipleExpectations + end + end + end end end diff --git a/spec/unit/facter/util/fact_rabbitmq_clustername_spec.rb b/spec/unit/facter/util/fact_rabbitmq_clustername_spec.rb new file mode 100644 index 0000000..1f74884 --- /dev/null +++ b/spec/unit/facter/util/fact_rabbitmq_clustername_spec.rb @@ -0,0 +1,77 @@ +require 'spec_helper' + +describe Facter::Util::Fact do + before do + Facter.clear + end + + describe 'rabbitmq_clusternam' do + context 'with value' do + it do + Facter::Util::Resolution.expects(:which).with('rabbitmqctl').returns(true) + Facter::Core::Execution.expects(:execute).with('rabbitmqctl -q cluster_status 2>&1').returns(' {cluster_name,<<"monty">>},') + expect(Facter.fact(:rabbitmq_clustername).value).to eq('monty') + end + end + + context 'with dashes in hostname' do + it do + Facter::Util::Resolution.expects(:which).with('rabbitmqctl').returns(true) + Facter::Core::Execution.expects(:execute).with('rabbitmqctl -q cluster_status 2>&1').returns('Cluster name: rabbit-1') + expect(Facter.fact(:rabbitmq_clustername).value).to eq('rabbit-1') + end + end + + context 'with dashes in clustername/hostname' do + it do + Facter::Util::Resolution.expects(:which).with('rabbitmqctl').returns(true) + Facter::Core::Execution.expects(:execute).with('rabbitmqctl -q cluster_status 2>&1').returns(' {cluster_name,<<"monty-python@rabbit-1">>},') + expect(Facter.fact(:rabbitmq_clustername).value).to eq('monty-python@rabbit-1') + end + end + + context 'with quotes around node name' do + it do + Facter::Util::Resolution.expects(:which).with('rabbitmqctl').returns(true) + Facter::Core::Execution.expects(:execute).with('rabbitmqctl -q cluster_status 2>&1').returns("monty\npython\nCluster name: 'monty@rabbit-1'\nend\nof\nfile") + expect(Facter.fact(:rabbitmq_clustername).value).to eq("'monty@rabbit-1'") + end + end + + context 'rabbitmq is not running' do + it do + error_string = <<-EOS +Status of node 'monty@rabbit-1' ... +Error: unable to connect to node 'monty@rabbit-1': nodedown + +DIAGNOSTICS +=========== + +attempted to contact: ['monty@rabbit-1'] + +monty@rabbit-1: + * connected to epmd (port 4369) on centos-7-x64 + * epmd reports: node 'rabbit' not running at all + no other nodes on centos-7-x64 + * suggestion: start the node + +current node details: +- node name: 'rabbitmq-cli-73@centos-7-x64' +- home dir: /var/lib/rabbitmq +- cookie hash: 6WdP0nl6d3HYqA5vTKMkIg== + + EOS + Facter::Util::Resolution.expects(:which).with('rabbitmqctl').returns(true) + Facter::Core::Execution.expects(:execute).with('rabbitmqctl -q cluster_status 2>&1').returns(error_string) + expect(Facter.fact(:rabbitmq_clustername).value).to be_nil + end + end + + context 'rabbitmqctl is not in path' do + it do + Facter::Util::Resolution.expects(:which).with('rabbitmqctl').returns(false) + expect(Facter.fact(:rabbitmq_clustername).value).to be_nil + end + end + end +end diff --git a/spec/unit/puppet/provider/rabbitmq_cluster/rabbitmqctl_spec.rb b/spec/unit/puppet/provider/rabbitmq_cluster/rabbitmqctl_spec.rb new file mode 100644 index 0000000..f59cda9 --- /dev/null +++ b/spec/unit/puppet/provider/rabbitmq_cluster/rabbitmqctl_spec.rb @@ -0,0 +1,39 @@ +require 'spec_helper' + +provider_class = Puppet::Type.type(:rabbitmq_cluster).provider(:rabbitmqctl) +describe provider_class do + let(:resource) do + Puppet::Type::Rabbitmq_cluster.new( + name: 'test_cluster', + init_node: 'host1' + ) + end + let(:provider) { provider_class.new(resource) } + + describe '#exists?' do + it { + provider.expects(:rabbitmqctl).with('-q', 'cluster_status').returns( + 'Cluster name: test_cluster' + ) + expect(provider.exists?).to be true + } + end + + describe '#create on every other node' do + it 'joins a cluster or changes the cluster name' do + provider.expects(:rabbitmqctl).with('stop_app') + provider.expects(:rabbitmqctl).with('join_cluster', 'rabbit@host1', '--disc') + provider.expects(:rabbitmqctl).with('start_app') + provider.create + end + end + + describe '#destroy' do + it 'remove cluster setup' do + provider.expects(:rabbitmqctl).with('stop_app') + provider.expects(:rabbitmqctl).with('reset') + provider.expects(:rabbitmqctl).with('start_app') + provider.destroy + end + end +end diff --git a/spec/unit/puppet/type/rabbitmq_cluster_spec.rb b/spec/unit/puppet/type/rabbitmq_cluster_spec.rb new file mode 100644 index 0000000..2a02570 --- /dev/null +++ b/spec/unit/puppet/type/rabbitmq_cluster_spec.rb @@ -0,0 +1,28 @@ +require 'spec_helper' +describe Puppet::Type.type(:rabbitmq_cluster) do + let(:rabbitmq_cluster) do + Puppet::Type.type(:rabbitmq_cluster).new(name: 'test_cluster') + end + + it 'accepts a cluster name' do + rabbitmq_cluster[:name] = 'test_cluster' + expect(rabbitmq_cluster[:name]).to eq('test_cluster') + end + it 'requires a name' do + expect do + Puppet::Type.type(:rabbitmq_cluster).new({}) + end.to raise_error(Puppet::Error, 'Title or name must be provided') + end + it 'check if init_node set to host1' do + rabbitmq_cluster[:init_node] = 'host1' + expect(rabbitmq_cluster[:init_node]).to eq('host1') + end + it 'try to set node_disc_type to ram' do + rabbitmq_cluster[:node_disc_type] = 'ram' + expect(rabbitmq_cluster[:node_disc_type]).to eq('ram') + end + it 'node_disc_type not set should default to disc' do + rabbitmq_cluster[:name] = 'test_cluster' + expect(rabbitmq_cluster[:node_disc_type]).to eq('disc') + end +end