Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make bind parameter processing more flexible #154

Merged
merged 1 commit into from
Feb 16, 2015
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
55 changes: 40 additions & 15 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,8 @@ The haproxy module provides the ability to install, configure, and manage HAProx

##Module Description

HAProxy is a daemon for load-balancing and proxying TCP and HTTP-based services.
This module configures proxy servers and manages the configuration of backend member servers.
HAProxy is a daemon for load-balancing and proxying TCP and HTTP-based services.
This module configures proxy servers and manages the configuration of backend member servers.

##Setup

Expand Down Expand Up @@ -70,7 +70,7 @@ node 'haproxy-server' {

###Configuring haproxy options

The main [`haproxy` class](#class-haproxy) has many options for configuring your HAProxy server.
The main [`haproxy` class](#class-haproxy) has many options for configuring your HAProxy server.

```puppet
class { 'haproxy':
Expand Down Expand Up @@ -136,9 +136,10 @@ haproxy::listen { 'puppet00':
'balance' => 'roundrobin',
},
bind => {
'10.0.0.1:443' => ['ssl', 'crt', 'puppetlabs.com'],
'168.12.12.12:80' => [],
'192.168.122.42:80' => []
'10.0.0.1:443' => ['ssl', 'crt', 'puppetlabs.com'],
'168.12.12.12:80' => [],
'192.168.122.42:8000-8100' => ['ssl', 'crt', 'puppetlabs.com'],
':8443,:8444' => ['ssl', 'crt', 'internal.puppetlabs.com']
},
}
```
Expand Down Expand Up @@ -205,7 +206,7 @@ The resulting HAProxy server will automatically collect configurations from back

####Class: `haproxy`

This is the main class of the module, guiding the installation and configuration of at least one HAProxy server.
This is the main class of the module, guiding the installation and configuration of at least one HAProxy server.

**Parameters:**

Expand Down Expand Up @@ -267,14 +268,14 @@ Sets the name of the balancermember server in the listening service's configurat

####Defined Type: `haproxy::backend`

This type sets up a backend service configuration block inside the haproxy.cfg file on an HAProxy load balancer. Each backend service needs one or more load balancer member servers (declared with the [`haproxy::balancermember`](#defined-type-balancermember) defined type).
This type sets up a backend service configuration block inside the haproxy.cfg file on an HAProxy load balancer. Each backend service needs one or more load balancer member servers (declared with the [`haproxy::balancermember`](#defined-type-balancermember) defined type).

Using storeconfigs, you can export the `haproxy::balancermember` resources on all load balancer member servers and collect them on a single HAProxy load balancer server.

**Parameters**

#####`name`
Sets the backend service's name. Generally, it will be the namevar of the defined resource type. This value appears right after the 'backend' statement in haproxy.cfg
Sets the backend service's name. Generally, it will be the namevar of the defined resource type. This value appears right after the 'backend' statement in haproxy.cfg

#####`options`
A hash of options that are inserted into the backend service configuration block.
Expand Down Expand Up @@ -310,7 +311,19 @@ This type sets up a frontend service configuration block in haproxy.cfg. The HAP
Lists an array of options to be specified after the bind declaration in the bind's configuration block. **Deprecated**: This parameter is being deprecated in favor of $bind

#####`bind`
A hash of ipaddress:port, with the haproxy bind options the address will have in the listening service's configuration block.
A hash of listening addresses/ports, and a list of parameters that make up the listen service's `bind` lines. This is the most flexible way to configure listening services in a frontend or listen directive. See http://cbonte.github.io/haproxy-dconv/configuration-1.5.html#4.2-bind for details.

The hash keys represent the listening address and port, such as `192.168.122.1:80`, `10.1.1.1:8900-9000`, `:80,:8080` or `/var/run/haproxy-frontend.sock` and the key's value is an array of bind options for that listening address, such as `[ 'ssl', 'crt /etc/ssl/puppetlabs.com.crt', 'no-sslv3' ]`. Example:

```puppet
bind => {
'168.12.12.12:80' => [],
'192.168.1.10:8080,192.168.1.10:8081' => [],
'10.0.0.1:443-453' => ['ssl', 'crt', 'puppetlabs.com'],
':8443,:8444' => ['ssl', 'crt', 'internal.puppetlabs.com'],
'/var/run/haproxy-frontend.sock' => [ 'user root', 'mode 600', 'accept-proxy' ],
}
```

#####`ipaddress`
Specifies the IP address the proxy binds to. No value, '\*', and '0.0.0.0' mean that the proxy listens to all valid addresses on the system.
Expand All @@ -329,7 +342,7 @@ Sets the ports to listen on for the address specified in `ipaddress`. Accepts a

#####Example

To route traffic from port 8140 to all balancermembers added to a backend with the title 'puppet_backend00',
To route traffic from port 8140 to all balancermembers added to a backend with the title 'puppet_backend00',

```puppet
haproxy::frontend { 'puppet00':
Expand All @@ -351,7 +364,7 @@ haproxy::frontend { 'puppet00':

####Defined type: `haproxy::listen`

This type sets up a listening service configuration block inside the haproxy.cfg file on an HAProxy load balancer. Each listening service configuration needs one or more load balancer member server (declared with the [`haproxy::balancermember`](#defined-type-balancermember) defined type).
This type sets up a listening service configuration block inside the haproxy.cfg file on an HAProxy load balancer. Each listening service configuration needs one or more load balancer member server (declared with the [`haproxy::balancermember`](#defined-type-balancermember) defined type).

Using storeconfigs, you can export the `haproxy::balancermember` resources on all load balancer member servers and collect them on a single HAProxy load balancer server.

Expand All @@ -361,10 +374,22 @@ Using storeconfigs, you can export the `haproxy::balancermember` resources on al
Sets the options to be specified after the bind declaration in the listening service's configuration block. Displays as an array. **Deprecated**: This parameter is being deprecated in favor of $bind

#####`bind`
A hash of ipaddress:port, with the haproxy bind options the address will have in the listening service's configuration block.
A hash of listening addresses/ports, and a list of parameters that make up the listen service's `bind` lines. This is the most flexible way to configure listening services in a frontend or listen directive. See http://cbonte.github.io/haproxy-dconv/configuration-1.5.html#4.2-bind for details.

The hash keys represent the listening address and port, such as `192.168.122.1:80`, `10.1.1.1:8900-9000`, `:80,:8080` or `/var/run/haproxy-frontend.sock` and the key's value is an array of bind options for that listening address, such as `[ 'ssl', 'crt /etc/ssl/puppetlabs.com.crt', 'no-sslv3' ]`. Example:

```puppet
bind => {
'168.12.12.12:80' => [],
'192.168.1.10:8080,192.168.1.10:8081' => [],
'10.0.0.1:443-453' => ['ssl', 'crt', 'puppetlabs.com'],
':8443,:8444' => ['ssl', 'crt', 'internal.puppetlabs.com'],
'/var/run/haproxy-frontend.sock' => [ 'user root', 'mode 600', 'accept-proxy' ],
}
```

#####`collect_exported`
Enables exported resources from `haproxy::balancermember` to be collected, serving as a form of autodiscovery. Displays as a Boolean and defaults to 'true'.
Enables exported resources from `haproxy::balancermember` to be collected, serving as a form of autodiscovery. Displays as a Boolean and defaults to 'true'.

The 'true' value means exported balancermember resources, for the case when every balancermember node exports itself, will be collected. Whereas, 'false' means the existing declared balancermember resources will be relied on; this is meant for cases when you know the full set of balancermembers in advance and use `haproxy::balancermember` with array arguments, allowing you to deploy everything in a single run.

Expand Down Expand Up @@ -420,7 +445,7 @@ An array of groups in the userlist. See http://cbonte.github.io/haproxy-dconv/co

##Limitations

RedHat and Debian family OSes are officially supported. Tested and built on Ubuntu and CentOS.
RedHat and Debian family OSes are officially supported. Tested and built on Ubuntu and CentOS.

##Development

Expand Down
22 changes: 21 additions & 1 deletion spec/defines/frontend_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -172,7 +172,7 @@
) }
end

context "when bind options are provided and no ip" do
context "when bind parameter is used without ipaddress parameter" do
let(:params) do
{
:name => 'apache',
Expand All @@ -186,5 +186,25 @@
) }
end

context "when bind parameter is used with more complex address constructs" do
let(:params) do
{
:name => 'apache',
:bind => {
'1.1.1.1:80' => [],
':443,:8443' => [ 'ssl', 'crt public.puppetlabs.com', 'no-sslv3' ],
'2.2.2.2:8000-8010' => [ 'ssl', 'crt public.puppetlabs.com' ],
'fd@${FD_APP1}' => [],
'/var/run/ssl-frontend.sock' => [ 'user root', 'mode 600', 'accept-proxy' ]
},
}
end
it { should contain_concat__fragment('apache_frontend_block').with(
'order' => '15-apache-00',
'target' => '/etc/haproxy/haproxy.cfg',
'content' => "\nfrontend apache\n bind /var/run/ssl-frontend.sock user root mode 600 accept-proxy\n bind 1.1.1.1:80 \n bind 2.2.2.2:8000-8010 ssl crt public.puppetlabs.com\n bind :443,:8443 ssl crt public.puppetlabs.com no-sslv3\n bind fd@${FD_APP1} \n option tcplog\n"
) }
end

# C9950 C9951 C9952 WONTFIX
end
22 changes: 21 additions & 1 deletion spec/defines/listen_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -200,7 +200,7 @@
'content' => "\nlisten apache\n bind 1.1.1.1:80 the options go here\n balance roundrobin\n option tcplog\n option ssl-hello-chk\n"
) }
end
context "when bind options are provided and no ip" do
context "when bind parameter is used without ipaddress parameter" do
let(:params) do
{
:name => 'apache',
Expand All @@ -215,4 +215,24 @@
) }
end

context "when bind parameter is used with more complex address constructs" do
let(:params) do
{
:name => 'apache',
:bind => {
'1.1.1.1:80' => [],
':443,:8443' => [ 'ssl', 'crt public.puppetlabs.com', 'no-sslv3' ],
'2.2.2.2:8000-8010' => [ 'ssl', 'crt public.puppetlabs.com' ],
'fd@${FD_APP1}' => [],
'/var/run/ssl-frontend.sock' => [ 'user root', 'mode 600', 'accept-proxy' ]
},
}
end
it { should contain_concat__fragment('apache_listen_block').with(
'order' => '20-apache-00',
'target' => '/etc/haproxy/haproxy.cfg',
'content' => "\nlisten apache\n bind /var/run/ssl-frontend.sock user root mode 600 accept-proxy\n bind 1.1.1.1:80 \n bind 2.2.2.2:8000-8010 ssl crt public.puppetlabs.com\n bind :443,:8443 ssl crt public.puppetlabs.com no-sslv3\n bind fd@${FD_APP1} \n balance roundrobin\n option tcplog\n option ssl-hello-chk\n"
) }
end

end
33 changes: 11 additions & 22 deletions templates/fragments/_bind.erb
Original file line number Diff line number Diff line change
@@ -1,24 +1,10 @@
<% require 'ipaddr' -%>
<% if @bind
@bind.keys.uniq.sort.each do |virtual_ip|
if ip_port = virtual_ip.match(/^([A-Za-z0-9\.-]+):([0-9]+)$/)
ip = ip_port[1]
port = ip_port[2]
elsif virtual_ip.match(/^([A-Za-z0-9\.-]+)$/)
ip = virtual_ip
end
begin
IPAddr.new(ip)
valid_ip = true
rescue ArgumentError => e
valid_ip = false
end
if ! valid_ip and ! ip.match(/^[A-Za-z][A-Za-z0-9\.-]+$/) and ip != "*"
scope.function_fail(["Invalid IP address or hostname [#{ip}]"])
end
scope.function_fail(["Port #{port} for IP #{ip} is outside of range 1-65535"]) if port and (port.to_i < 1 or port.to_i > 65535) -%>
bind <%= ip -%>:<%= port -%> <%= Array(@bind[virtual_ip]).join(" ") %>
<%- end else
<%- if @bind -%>
<%- @bind.sort.map do |address_port, bind_params| -%>
bind <%= address_port -%> <%= Array(bind_params).join(" ") %>
<%- end -%>
<%- else -%>
<%-
Array(@ipaddress).uniq.each do |virtual_ip| (@ports.is_a?(Array) ? @ports : Array(@ports.split(","))).each do |port|
begin
IPAddr.new(virtual_ip)
Expand All @@ -29,6 +15,9 @@
if ! valid_ip and ! virtual_ip.match(/^[A-Za-z][A-Za-z0-9\.-]+$/) and virtual_ip != "*"
scope.function_fail(["Invalid IP address or hostname [#{virtual_ip}]"])
end
scope.function_fail(["Port [#{port}] is outside of range 1-65535"]) if port.to_i < 1 or port.to_i > 65535 -%>
scope.function_fail(["Port [#{port}] is outside of range 1-65535"]) if port.to_i < 1 or port.to_i > 65535
-%>
bind <%= virtual_ip -%>:<%= port -%> <%= Array(@bind_options).join(" ") %>
<%- end end end -%>
<%- end -%>
<%- end -%>
<%- end -%>