diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 280baa61..b2ad81f0 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -33,6 +33,7 @@ jobs: suite: - config-2 - config-3 + - config-4 - config-acl - config-array - config-backend-search diff --git a/CHANGELOG.md b/CHANGELOG.md index 4e725d95..d5d6556c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,9 @@ This file is used to list changes made in each version of the haproxy cookbook. ## Unreleased +- Add `option` property to `haproxy_listen` +- Refactor `option`s internally to not create an unnecessary nested array + ## 12.3.0 - *2024-01-31* - Update default HAProxy source install verision to 2.8.5 diff --git a/documentation/haproxy_listen.md b/documentation/haproxy_listen.md index 8416f33f..197ef74b 100644 --- a/documentation/haproxy_listen.md +++ b/documentation/haproxy_listen.md @@ -33,6 +33,7 @@ This resource also uses the following partial resources: | `server` | Array | None | Servers the listen section routes to | | | `stats` | Hash | None | Enable stats with various options | | | `hash_type` | String | None | Specify a method to use for mapping hashes to servers | `consistent`, `map-based` | +| `option` | Array | None | Array of HAProxy `option` directives | ## Examples diff --git a/resources/backend.rb b/resources/backend.rb index 81539697..1da26dca 100644 --- a/resources/backend.rb +++ b/resources/backend.rb @@ -54,7 +54,7 @@ if property_is_set?(:option) haproxy_config_resource.variables['backend'][new_resource.name]['option'] ||= [] - haproxy_config_resource.variables['backend'][new_resource.name]['option'].push(new_resource.option) + haproxy_config_resource.variables['backend'][new_resource.name]['option'].concat(new_resource.option) end haproxy_config_resource.variables['backend'][new_resource.name]['hash_type'] = new_resource.hash_type if property_is_set?(:hash_type) diff --git a/resources/fastcgi.rb b/resources/fastcgi.rb index 70729dbb..eb7313e3 100644 --- a/resources/fastcgi.rb +++ b/resources/fastcgi.rb @@ -37,7 +37,7 @@ if property_is_set?(:option) haproxy_config_resource.variables['fastcgi'][new_resource.name]['option'] ||= [] - haproxy_config_resource.variables['fastcgi'][new_resource.name]['option'].push(new_resource.option) + haproxy_config_resource.variables['fastcgi'][new_resource.name]['option'].concat(new_resource.option) end haproxy_config_resource.variables['fastcgi'][new_resource.name]['extra_options'] = new_resource.extra_options if property_is_set?(:extra_options) diff --git a/resources/frontend.rb b/resources/frontend.rb index 9f5b16d3..6d38e428 100644 --- a/resources/frontend.rb +++ b/resources/frontend.rb @@ -65,7 +65,7 @@ if property_is_set?(:option) haproxy_config_resource.variables['frontend'][new_resource.name]['option'] ||= [] - haproxy_config_resource.variables['frontend'][new_resource.name]['option'].push(new_resource.option) + haproxy_config_resource.variables['frontend'][new_resource.name]['option'].concat(new_resource.option) end haproxy_config_resource.variables['frontend'][new_resource.name]['extra_options'] = new_resource.extra_options if property_is_set?(:extra_options) diff --git a/resources/listen.rb b/resources/listen.rb index 4dad2a0d..6eb30d41 100644 --- a/resources/listen.rb +++ b/resources/listen.rb @@ -38,6 +38,9 @@ equal_to: %w(consistent map-based), description: 'Specify a method to use for mapping hashes to servers' +property :option, Array, + description: 'Array of HAProxy option directives' + unified_mode true action_class do @@ -87,6 +90,11 @@ haproxy_config_resource.variables['listen'][new_resource.name]['hash_type'] = new_resource.hash_type if property_is_set?(:hash_type) haproxy_config_resource.variables['listen'][new_resource.name]['extra_options'] = new_resource.extra_options if property_is_set?(:extra_options) + + if property_is_set?(:option) + haproxy_config_resource.variables['listen'][new_resource.name]['option'] ||= [] + haproxy_config_resource.variables['listen'][new_resource.name]['option'].concat(new_resource.option) + end end action :delete do diff --git a/templates/default/haproxy.cfg.erb b/templates/default/haproxy.cfg.erb index 019d2586..98531115 100644 --- a/templates/default/haproxy.cfg.erb +++ b/templates/default/haproxy.cfg.erb @@ -221,11 +221,9 @@ fcgi-app <%= fastcgi %> <% end -%> <% unless nil_or_empty?(f['option']) %> <% f['option'].each do | option |%> -<% option.each do | option | %> option <%= option %> <% end -%> <% end -%> -<% end -%> <% unless nil_or_empty?(f['extra_options']) %> <% f['extra_options'].each do | key, value | %> <% unless key == 'http-request' %> @@ -286,11 +284,9 @@ frontend <%= frontend %> <% end -%> <% unless nil_or_empty?(f['option']) %> <% f['option'].each do | option |%> -<% option.each do | option | %> option <%= option %> <% end -%> <% end -%> -<% end -%> <% unless nil_or_empty?(f['extra_options']) %> <% f['extra_options'].each do | key, value | %> <% unless key == 'http-request' %> @@ -328,11 +324,9 @@ backend <%= key %> <% end -%> <% unless nil_or_empty?(backend['option']) %> <% backend['option'].each do | option |%> -<% option.each do | option | %> option <%= option %> <% end -%> <% end -%> -<% end -%> <% unless nil_or_empty?(backend['tcp_request']) %> <% backend['tcp_request'].each do | tcp_request |%> <% tcp_request.each do | tcp_request | %> @@ -389,6 +383,11 @@ listen <%= key %> <% if listen['default_backend'] -%> default_backend <%= listen['default_backend'] %> <% end %> +<% unless nil_or_empty?(listen['option']) %> +<% listen['option'].each do | option |%> + option <%= option %> +<% end -%> +<% end -%> <% unless nil_or_empty?(listen['extra_options']) %> <% listen['extra_options'].each do | key, value | %> <% if key == 'http-request' %> diff --git a/test/cookbooks/test/recipes/config_4.rb b/test/cookbooks/test/recipes/config_4.rb new file mode 100644 index 00000000..4c201de5 --- /dev/null +++ b/test/cookbooks/test/recipes/config_4.rb @@ -0,0 +1,82 @@ +apt_update + +haproxy_install 'package' + +haproxy_config_global '' + +haproxy_config_defaults '' do + hash_type 'consistent' +end + +haproxy_listen 'admin' do + bind '0.0.0.0:1337' + mode 'http' + stats uri: '/', + realm: 'Haproxy-Statistics', + auth: 'user:pwd' + http_request [ + 'add-header X-Forwarded-Proto https if { ssl_fc }', + 'add-header X-Proto http', + ] + http_response 'set-header Expires %[date(3600),http_date]' + default_backend 'servers' + option %w(dontlog-normal) + extra_options('bind-process' => 'odd') + hash_type 'consistent' +end + +haproxy_listen 'single-reqrep-reqirep' do + bind '0.0.0.0:8001' + default_backend 'servers' + reqrep '^Host:\ ftp.mydomain.com Host:\ ftp' + reqirep '^Host:\ www.mydomain.com Host:\ www' +end + +haproxy_listen 'multi-reqrep' do + bind '0.0.0.0:8002' + default_backend 'servers' + reqrep [ + '^Host:\ ftp.mydomain.com Host:\ ftp', + '^Host:\ www.mydomain.com Host:\ www', + ] +end + +haproxy_listen 'multi-reqirep' do + bind '0.0.0.0:8003' + default_backend 'servers' + reqirep [ + '^Host:\ ftp.mydomain.com Host:\ ftp', + '^Host:\ www.mydomain.com Host:\ www', + ] +end + +haproxy_backend 'servers' do + server ['disabled-server 127.0.0.1:1 disabled'] + hash_type 'consistent' +end + +haproxy_backend 'single-reqrep-reqirep' do + server ['disabled-server 127.0.0.1:1 disabled'] + reqrep '^Host:\ ftp.mydomain.com Host:\ ftp' + reqirep '^Host:\ www.mydomain.com Host:\ www' +end + +haproxy_backend 'multi-reqrep' do + server ['disabled-server 127.0.0.1:1 disabled'] + reqrep [ + '^Host:\ ftp.mydomain.com Host:\ ftp', + '^Host:\ www.mydomain.com Host:\ www', + ] +end + +haproxy_backend 'multi-reqirep' do + server ['disabled-server 127.0.0.1:1 disabled'] + reqirep [ + '^Host:\ ftp.mydomain.com Host:\ ftp', + '^Host:\ www.mydomain.com Host:\ www', + ] +end + +haproxy_service 'haproxy' do + action %i(create enable start) +end diff --git a/test/integration/config_4/example_spec.rb b/test/integration/config_4/example_spec.rb new file mode 100644 index 00000000..9e2cb8b0 --- /dev/null +++ b/test/integration/config_4/example_spec.rb @@ -0,0 +1,104 @@ +describe package('haproxy') do + it { should be_installed } +end + +describe directory '/etc/haproxy' do + it { should exist } +end + +describe file('/etc/haproxy/haproxy.cfg') do + it { should exist } + it { should be_owned_by 'haproxy' } + it { should be_grouped_into 'haproxy' } + cfg_content = [ + 'global', + ' user haproxy', + ' group haproxy', + ' log /dev/log syslog info', + ' log-tag haproxy', + ' daemon', + ' quiet', + ' stats socket /var/run/haproxy.sock user haproxy group haproxy', + ' stats timeout 2m', + ' maxconn 4096', + ' pidfile /var/run/haproxy.pid', + '', + '', + 'defaults', + ' timeout client 10s', + ' timeout server 10s', + ' timeout connect 10s', + ' log global', + ' mode http', + ' balance roundrobin', + ' hash-type consistent', + ' option httplog', + ' option dontlognull', + ' option redispatch', + ' option tcplog', + '', + '', + 'backend servers', + ' server disabled-server 127.0.0.1:1 disabled', + ' hash-type consistent', + '', + '', + 'backend single-reqrep-reqirep', + ' server disabled-server 127.0.0.1:1 disabled', + ' reqrep \^Host:\\\ ftp.mydomain.com Host:\\\ ftp', + ' reqirep \^Host:\\\ www.mydomain.com Host:\\\ www', + '', + '', + 'backend multi-reqrep', + ' server disabled-server 127.0.0.1:1 disabled', + ' reqrep \^Host:\\\ ftp.mydomain.com Host:\\\ ftp', + ' reqrep \^Host:\\\ www.mydomain.com Host:\\\ www', + '', + '', + 'backend multi-reqirep', + ' server disabled-server 127.0.0.1:1 disabled', + ' reqirep \^Host:\\\ ftp.mydomain.com Host:\\\ ftp', + ' reqirep \^Host:\\\ www.mydomain.com Host:\\\ www', + '', + '', + 'listen admin', + ' mode http', + ' bind 0.0.0.0:1337', + ' stats uri /', + ' stats realm Haproxy-Statistics', + ' stats auth user:pwd', + ' http-request add-header X-Forwarded-Proto https if { ssl_fc }', + ' http-request add-header X-Proto http', + ' http-response set-header Expires %\[date\(3600\),http_date\]', + ' default_backend servers', + ' option dontlog-normal', + ' bind-process odd', + ' hash-type consistent', + '', + '', + 'listen single-reqrep-reqirep', + ' bind 0.0.0.0:8001', + ' reqrep \^Host:\\\ ftp.mydomain.com Host:\\\ ftp', + ' reqirep \^Host:\\\ www.mydomain.com Host:\\\ www', + ' default_backend servers', + '', + '', + 'listen multi-reqrep', + ' bind 0.0.0.0:8002', + ' reqrep \^Host:\\\ ftp.mydomain.com Host:\\\ ftp', + ' reqrep \^Host:\\\ www.mydomain.com Host:\\\ www', + ' default_backend servers', + '', + '', + 'listen multi-reqirep', + ' bind 0.0.0.0:8003', + ' reqirep \^Host:\\\ ftp.mydomain.com Host:\\\ ftp', + ' reqirep \^Host:\\\ www.mydomain.com Host:\\\ www', + ' default_backend servers', + ] + its('content') { should match /#{cfg_content.join('\n')}/ } +end + +describe service('haproxy') do + it { should be_running } +end