diff --git a/manifests/config.pp b/manifests/config.pp index bc1ed091..65e22263 100644 --- a/manifests/config.pp +++ b/manifests/config.pp @@ -9,6 +9,7 @@ Hash $global_options, Hash $defaults_options, Boolean $chroot_dir_manage, + Haproxy::Programs $programs = {}, Stdlib::Absolutepath $config_dir = undef, Optional[String] $custom_fragment = undef, Boolean $merge_options = $haproxy::merge_options, @@ -81,6 +82,10 @@ order => '10', content => epp("${module_name}/haproxy-base.cfg.epp", $parameters), } + + if !empty($programs) { + create_resources(haproxy::program, $programs) + } } if $chroot_dir_manage { diff --git a/manifests/init.pp b/manifests/init.pp index be81a56a..15220666 100644 --- a/manifests/init.pp +++ b/manifests/init.pp @@ -63,6 +63,11 @@ # Passed directly as the 'restart' parameter to the service resource. # Defaults to undef i.e. whatever the service default is. # +# @param programs +# A program section contains a set of directives that define the program to be run, +# its command-line options and flags, as well as user, group, and restart options. +# Note, `master-worker` configuration (in `global_options`) is needed. +# # @param custom_fragment # Allows arbitrary HAProxy configuration to be passed through to support # additional configuration not available via parameters, or to short-circute @@ -131,6 +136,7 @@ Hash $global_options = $haproxy::params::global_options, Hash $defaults_options = $haproxy::params::defaults_options, Boolean $merge_options = $haproxy::params::merge_options, + Haproxy::Programs $programs = {}, Optional[String] $restart_command = undef, Optional[String] $custom_fragment = undef, Stdlib::Absolutepath $config_dir = $haproxy::params::config_dir, @@ -187,5 +193,6 @@ service_options => $service_options, sysconfig_options => $sysconfig_options, config_validate_cmd => $config_validate_cmd, + programs => $programs, } } diff --git a/manifests/instance.pp b/manifests/instance.pp index 9e42e015..ba87250e 100644 --- a/manifests/instance.pp +++ b/manifests/instance.pp @@ -85,6 +85,10 @@ # # @param sysconfig_options # +# @param programs +# A program section contains a set of directives that define the program to be run, +# its command-line options and flags, as well as user, group, and restart options. +# # @example # A single instance of haproxy with all defaults # i.e. emulate Class['haproxy'] @@ -175,6 +179,7 @@ Boolean $merge_options = $haproxy::params::merge_options, String $service_options = $haproxy::params::service_options, String $sysconfig_options = $haproxy::params::sysconfig_options, + Haproxy::Programs $programs = {}, ) { # Since this is a 'define', we can not use 'inherts haproxy::params'. # Therefore, we "include haproxy::params" for any parameters we need. @@ -221,6 +226,7 @@ package_ensure => $package_ensure, chroot_dir_manage => $chroot_dir_manage, config_validate_cmd => $config_validate_cmd, + programs => $programs, } haproxy::install { $title: package_name => $package_name, diff --git a/manifests/program.pp b/manifests/program.pp new file mode 100644 index 00000000..8afec086 --- /dev/null +++ b/manifests/program.pp @@ -0,0 +1,40 @@ +# @summary Program definition +# +# A command to be executed by haproxy master process +# +# @see https://www.haproxy.com/documentation/haproxy-configuration-tutorials/programs/ +# @example +# haproxy::program { 'hello': +# command => 'hello world', +# } +define haproxy::program ( + String $command, + Optional[String] $user = undef, + Optional[String] $group = undef, + Optional[String] $options = undef, + String $instance = 'haproxy', + Optional[Stdlib::Absolutepath] $config_file = undef, +) { + # We derive these settings so that the caller only has to specify $instance. + include haproxy::params + + if $instance == 'haproxy' { + $instance_name = 'haproxy' + $_config_file = pick($config_file, $haproxy::config_file) + } else { + $instance_name = "haproxy-${instance}" + $_config_file = pick($config_file, inline_template($haproxy::params::config_file_tmpl)) + } + + concat::fragment { "${instance_name}-${name}_program": + order => "40-program-${name}", + target => $_config_file, + content => epp('haproxy/haproxy_program.epp', { + 'name' => $name, + 'command' => $command, + 'user' => $user, + 'group' => $group, + 'options' => $options, + }), + } +} diff --git a/spec/classes/haproxy_spec.rb b/spec/classes/haproxy_spec.rb index b43aafc8..d2eee2d4 100644 --- a/spec/classes/haproxy_spec.rb +++ b/spec/classes/haproxy_spec.rb @@ -668,4 +668,31 @@ }.to raise_error(Puppet::Error, %r{operating system is not supported with the haproxy module}) end end + + describe 'when programs is specified' do + ['Debian'].each do |osfamily| + context "when on #{osfamily} family operatingsystems" do + let(:facts) do + { os: { family: osfamily } }.merge default_facts + end + let(:contents) { param_value(catalogue, 'concat::fragment', 'haproxy-haproxy-base', 'content').split("\n") } + let(:params) do + { + 'programs' => { + 'foo' => { + 'command' => '/usr/bin/foo', + }, + 'bar' => { + 'command' => '/usr/bin/bar', + }, + }, + } + end + + it { is_expected.to compile } + it { is_expected.to contain_concat__fragment('haproxy-foo_program').with_content(%r{command /usr/bin/foo}) } + it { is_expected.to contain_concat__fragment('haproxy-bar_program').with_content(%r{command /usr/bin/bar}) } + end + end + end end diff --git a/spec/defines/program_spec.rb b/spec/defines/program_spec.rb new file mode 100644 index 00000000..ccf34105 --- /dev/null +++ b/spec/defines/program_spec.rb @@ -0,0 +1,37 @@ +# frozen_string_literal: true + +require 'spec_helper' + +describe 'haproxy::program' do + let :pre_condition do + 'class{"haproxy": + config_file => "/tmp/haproxy.cfg" + } + ' + end + let(:facts) do + { + concat_basedir: '/foo', + os: { + family: 'Debian' + } + } + end + + context 'simple program' do + let(:title) { 'hello' } + let(:params) do + { + command: 'echo "hello world"', + } + end + + it { + is_expected.to contain_concat__fragment('haproxy-hello_program').with( + 'order' => '40-program-hello', + 'target' => '/tmp/haproxy.cfg', + 'content' => %r{command echo "hello world"}, + ) + } + end +end diff --git a/templates/haproxy_program.epp b/templates/haproxy_program.epp new file mode 100644 index 00000000..cffbad4f --- /dev/null +++ b/templates/haproxy_program.epp @@ -0,0 +1,11 @@ +program <%= $name %> + command <%= $command %> + <% if $user { -%> + user <%= $user %> + <% } -%> + <% if $group { -%> + group $group + <% } -%> + <% if $options { -%> + <%= $options %> + <% } -%> diff --git a/types/programs.pp b/types/programs.pp new file mode 100644 index 00000000..37eca453 --- /dev/null +++ b/types/programs.pp @@ -0,0 +1,9 @@ +type Haproxy::Programs = Hash[String, Struct[{ + command => String[1], + Optional[user] => String[1], + Optional[group] => String[1], + Optional[options] => String[1], + Optional[instance] => String[1], + Optional[config_file] => Stdlib::Absolutepath, +}]] +