diff --git a/README.md b/README.md index 1544af0b..e40083ac 100644 --- a/README.md +++ b/README.md @@ -456,6 +456,8 @@ haproxy::frontend { 'ft_allapps': * [`haproxy::userlist`](#define-haproxyuserlist): Creates a userlist entry in haproxy.cfg. * [`haproxy::peers`](#define-haproxypeers): Creates a peers entry in haproxy.cfg. * [`haproxy::peer`](#define-haproxypeer): Creates server entries within a peers entry in haproxy.cfg. +* [`haproxy::mailers`](#define-haproxymailers): Creates a mailers entry in haproxy.cfg. +* [`haproxy::mailer`](#define-haproxymailer): Creates server entries within a mailers entry in haproxy.cfg. * [`haproxy::instance`](#define-instance): Creates multiple instances of haproxy on the same machine. * [`haproxy::instance_service`](#define-instanceservice): Example of one way to prepare environment for haproxy::instance. * [`haproxy::mapfile`](#define-haproxymapfile): Manages an HAProxy [map file](https://cbonte.github.io/haproxy-dconv/configuration-1.5.html#7.3.1-map). @@ -464,6 +466,7 @@ haproxy::frontend { 'ft_allapps': * `haproxy::balancermember::collect_exported`: Collects exported balancermembers. * `haproxy::peer::collect_exported`: Collects exported peers. +* `haproxy::mailer::collect_exported`: Collects exported mailers. #### Class: `haproxy` @@ -726,8 +729,6 @@ Sets up a peer entry inside the peers configuration block in haproxy.cfg. ##### Parameters -* `ensure`: Specifies whether the peer should exist in the configuration block. Valid options: 'present' or 'absent'. Default: 'present'. - * `ipaddresses`: *Required unless the `collect_exported` parameter of your `haproxy::peers` resource is set to `true`.* Specifies the IP address used to contact the peer member server. Valid options: a string or an array. If you pass an array, it must contain the same number of elements as the array you pass to the `server_names` parameter. Puppet pairs up the elements from both arrays and creates a peer for each pair of values. Default: the value of the `$::ipaddress` fact. * `peers_name`: *Required.* Specifies the peer in which to add the load balancer. Valid options: a string containing the name of an HAProxy peer. @@ -738,6 +739,33 @@ Sets up a peer entry inside the peers configuration block in haproxy.cfg. * `instance`: *Optional.* When using `haproxy::instance` to run multiple instances of Haproxy on the same machine, this indicates which instance. Defaults to "haproxy". +#### Define: `haproxy::mailers` + +Sets up a mailers entry in haproxy.cfg on the load balancer to send email to each mailer that is configured in a mailers section alerts when the state of servers changes. + +##### Parameters + +* `collect_exported`: *Optional.* Specifies whether to collect resources exported by other nodes. This serves as a form of autodiscovery. Valid options: 'true' and 'false'. Default: 'true'. + +* `name`: *Optional.* Appends a name to the mailers entry in haproxy.cfg. Valid options: a string. Default: the title of your declared resource. + +* `instance`: *Optional.* When using `haproxy::instance` to run multiple instances of Haproxy on the same machine, this indicates which instance. Defaults to "haproxy". + +#### Define: `haproxy::mailer` + +Sets up a mailer entry inside the mailers configuration block in haproxy.cfg. + +##### Parameters +* `ipaddresses`: *Required unless the `collect_exported` parameter of your `haproxy::mailers` resource is set to `true`.* Specifies the IP address used to contact the mailer email server. Valid options: a string or an array. If you pass an array, it must contain the same number of elements as the array you pass to the `server_names` parameter. Puppet pairs up the elements from both arrays and creates a mailer for each pair of values. Default: the value of the `$::ipaddress` fact. + +* `mailers_name`: *Required.* Specifies the name of a valid `haproxy::mailers` resource. Valid options: a string containing the name of an HAProxy mailer. + +* `port`: *Required.* Specifies the port to which the load balancer makes its smtp connection. Valid options: a string containing a port number. + +* `server_names`: *Required unless the `collect_exported` parameter of your `haproxy::mailers` resource is set to `true`.* Sets the name of the email server as listed in the mailers configuration block. Valid options: a string or an array. If you pass an array, it must contain the same number of elements as the array you pass to `ipaddresses`. Puppet pairs up the elements from both arrays and creates a mailer for each pair of values. Default: the value of the `$::hostname` fact. + +* `instance`: *Optional.* When using `haproxy::instance` to run multiple instances of Haproxy on the same machine, this indicates which instance. Defaults to "haproxy". + #### Define: `haproxy::instance` Runs multiple instances of haproxy on the same machine. Normally users diff --git a/manifests/backend.pp b/manifests/backend.pp index af55823c..a2d5a4a8 100644 --- a/manifests/backend.pp +++ b/manifests/backend.pp @@ -64,7 +64,7 @@ 'option' => [ 'tcplog', ], - 'balance' => 'roundrobin' + 'balance' => 'roundrobin', }, $instance = 'haproxy', $section_name = $name, @@ -74,7 +74,7 @@ fail("An haproxy::listen resource was discovered with the same name (${section_name}) which is not supported") } - include haproxy::params + include ::haproxy::params if $instance == 'haproxy' { $instance_name = 'haproxy' $config_file = $haproxy::params::config_file @@ -82,7 +82,7 @@ $instance_name = "haproxy-${instance}" $config_file = inline_template($haproxy::params::config_file_tmpl) } - include haproxy::globals + include ::haproxy::globals $_sort_options_alphabetic = pick($sort_options_alphabetic, $haproxy::globals::sort_options_alphabetic) # Template uses: $section_name, $ipaddress, $ports, $options diff --git a/manifests/mailer.pp b/manifests/mailer.pp new file mode 100644 index 00000000..31863750 --- /dev/null +++ b/manifests/mailer.pp @@ -0,0 +1,54 @@ +# == Define Resource Type: haproxy::mailer +# +# This type will set up a mailer entry inside the mailers configuration block in +# haproxy.cfg on the load balancer. Currently, it has the ability to +# specify the instance name, ip address, ports and server_names. +# +# Automatic discovery of mailer nodes may be implemented by exporting the mailer +# resource for all HAProxy balancer servers that are configured in the same HA +# block and then collecting them on all load balancers. +# +# === Parameters: +# +# [*mailers_name*] +# Specifies the mailer in which this load balancer needs to be added. +# +# [*server_names*] +# Sets the name of the mailer server in the mailers configuration block. +# Defaults to the hostname. Can be an array. If this parameter is +# specified as an array, it must be the same length as the +# ipaddresses parameter's array. A mailer is created for each pair +# of server\_names and ipaddresses in the array. +# +# [*ipaddresses*] +# Specifies the IP address used to contact the mailer member server. +# Can be an array. If this parameter is specified as an array it +# must be the same length as the server\_names parameter's array. +# A mailer is created for each pair of address and server_name. +# +# [*ports*] +# Sets the port on which the mailer is going to share the state. + +define haproxy::mailer ( + $mailers_name, + $port, + $server_names = $::hostname, + $ipaddresses = $::ipaddress, + $instance = 'haproxy', +) { + include ::haproxy::params + if $instance == 'haproxy' { + $instance_name = 'haproxy' + $config_file = $::haproxy::config_file + } else { + $instance_name = "haproxy-${instance}" + $config_file = inline_template($haproxy::params::config_file_tmpl) + } + + # Templates uses $ipaddresses, $server_name, $ports, $option + concat::fragment { "${instance_name}-mailers-${mailers_name}-${name}": + order => "40-mailers-01-${mailers_name}-${name}", + target => $config_file, + content => template('haproxy/haproxy_mailer.erb'), + } +} diff --git a/manifests/mailer/collect_exported.pp b/manifests/mailer/collect_exported.pp new file mode 100644 index 00000000..1d925ea3 --- /dev/null +++ b/manifests/mailer/collect_exported.pp @@ -0,0 +1,8 @@ +# Private define +define haproxy::mailer::collect_exported { + if $caller_module_name != $module_name { + fail("Use of private class ${name} by ${caller_module_name}") + } + + Haproxy::Mailer <<| mailers_name == $name |>> +} diff --git a/manifests/mailers.pp b/manifests/mailers.pp new file mode 100644 index 00000000..86b1929d --- /dev/null +++ b/manifests/mailers.pp @@ -0,0 +1,40 @@ +# == Defined Type: haproxy::mailers +# +# This type will set up a mailers entry in haproxy.cfg on the load balancer. +# This setting makes it possible to send emails during state changes. +# +# === Parameters +# +# [*name*] +# Sets the mailers' name. Generally it will be the namevar of the +# defined resource type. This value appears right after the +# 'mailers' statement in haproxy.cfg + +define haproxy::mailers ( + $collect_exported = true, + $instance = 'haproxy', +) { + + # We derive these settings so that the caller only has to specify $instance. + include ::haproxy::params + if $instance == 'haproxy' { + $instance_name = 'haproxy' + $config_file = $::haproxy::config_file + } else { + $instance_name = "haproxy-${instance}" + $config_file = inline_template($haproxy::params::config_file_tmpl) + } + + # Template uses: $name + concat::fragment { "${instance_name}-${name}_mailers_block": + order => "40-mailers-00-${name}", + target => $config_file, + content => template('haproxy/haproxy_mailers_block.erb'), + } + + if $collect_exported { + haproxy::mailer::collect_exported { $name: } + } + # else: the resources have been created and they introduced their + # concat fragments. We don't have to do anything about them. +} diff --git a/manifests/peer.pp b/manifests/peer.pp index 69e81c61..6fb6e10f 100644 --- a/manifests/peer.pp +++ b/manifests/peer.pp @@ -20,10 +20,6 @@ # ipaddresses parameter's array. A peer is created for each pair # of server\_names and ipaddresses in the array. # -# [*ensure*] -# Whether to add or remove the peer. Defaults to 'present'. -# Valid values are 'present' and 'absent'. -# # [*ipaddresses*] # Specifies the IP address used to contact the peer member server. # Can be an array. If this parameter is specified as an array it @@ -36,13 +32,17 @@ define haproxy::peer ( $peers_name, $port, - $ensure = 'present', $server_names = $::hostname, $ipaddresses = $::ipaddress, - $instance = 'haproxy', -) { + $instance = 'haproxy', - include haproxy::params + #Deprecated + $ensure = undef, +) { + if $ensure { + warning('ensure is deprecated') + } + include ::haproxy::params if $instance == 'haproxy' { $instance_name = 'haproxy' $config_file = $::haproxy::config_file @@ -53,7 +53,6 @@ # Templates uses $ipaddresses, $server_name, $ports, $option concat::fragment { "${instance_name}-peers-${peers_name}-${name}": - ensure => $ensure, order => "30-peers-01-${peers_name}-${name}", target => $config_file, content => template('haproxy/haproxy_peer.erb'), diff --git a/manifests/peers.pp b/manifests/peers.pp index b227cee9..ffaf4be6 100644 --- a/manifests/peers.pp +++ b/manifests/peers.pp @@ -18,7 +18,7 @@ ) { # We derive these settings so that the caller only has to specify $instance. - include haproxy::params + include ::haproxy::params if $instance == 'haproxy' { $instance_name = 'haproxy' $config_file = $::haproxy::config_file @@ -27,7 +27,7 @@ $config_file = inline_template($haproxy::params::config_file_tmpl) } - # Template uses: $name, $ipaddress, $ports, $options + # Template uses: $name concat::fragment { "${instance_name}-${name}_peers_block": order => "30-peers-00-${name}", target => $config_file, diff --git a/spec/defines/mailer_spec.rb b/spec/defines/mailer_spec.rb new file mode 100644 index 00000000..0976b164 --- /dev/null +++ b/spec/defines/mailer_spec.rb @@ -0,0 +1,34 @@ +require 'spec_helper' + +describe 'haproxy::mailer' do + let :pre_condition do + 'class{"haproxy": + config_file => "/tmp/haproxy.cfg" + } + ' + end + let(:title) { 'dero' } + let(:facts) do + { + :ipaddress => '1.1.1.1', + :hostname => 'dero', + :concat_basedir => '/foo', + :osfamily => 'RedHat', + } + end + + context 'with a single mailer' do + let(:params) do + { + :mailers_name => 'tyler', + :port => 1024, + } + end + + it { should contain_concat__fragment('haproxy-mailers-tyler-dero').with( + 'order' => '40-mailers-01-tyler-dero', + 'target' => '/tmp/haproxy.cfg', + 'content' => " mailer dero 1.1.1.1:1024\n" + ) } + end +end diff --git a/spec/defines/mailers_spec.rb b/spec/defines/mailers_spec.rb new file mode 100644 index 00000000..3ce72623 --- /dev/null +++ b/spec/defines/mailers_spec.rb @@ -0,0 +1,25 @@ +require 'spec_helper' + +describe 'haproxy::mailers' do + let :pre_condition do + 'class{"haproxy": + config_file => "/tmp/haproxy.cfg" + } + ' + end + let(:facts) {{ + :ipaddress => '1.1.1.1', + :concat_basedir => '/foo', + :osfamily => 'RedHat', + }} + + context "when no options are passed" do + let(:title) { 'bar' } + + it { should contain_concat__fragment('haproxy-bar_mailers_block').with( + 'order' => '40-mailers-00-bar', + 'target' => '/tmp/haproxy.cfg', + 'content' => "\nmailers bar\n" + ) } + end +end diff --git a/spec/defines/peer_spec.rb b/spec/defines/peer_spec.rb index 6dc77141..e4a564d1 100644 --- a/spec/defines/peer_spec.rb +++ b/spec/defines/peer_spec.rb @@ -31,18 +31,4 @@ 'content' => " peer dero 1.1.1.1:1024\n" ) } end - - context 'remove a peer' do - let(:params) do - { - :peers_name => 'tyler', - :port => 1024, - :ensure => 'absent' - } - end - - it { should contain_concat__fragment('haproxy-peers-tyler-dero').with( - 'ensure' => 'absent' - ) } - end end diff --git a/templates/haproxy_mailer.erb b/templates/haproxy_mailer.erb new file mode 100644 index 00000000..ae466651 --- /dev/null +++ b/templates/haproxy_mailer.erb @@ -0,0 +1,3 @@ +<% Array(@ipaddresses).zip(Array(@server_names)).each do |ipaddress,host| -%> + mailer <%= host %> <%= ipaddress %>:<%= @port %> +<% end -%> diff --git a/templates/haproxy_mailers_block.erb b/templates/haproxy_mailers_block.erb new file mode 100644 index 00000000..05d4d523 --- /dev/null +++ b/templates/haproxy_mailers_block.erb @@ -0,0 +1,2 @@ + +mailers <%= @name %>