Adapt new haproxy module to Fuel
Change-Id: I48038540d2a69a116521466369aaaddae02bceb3 Implements: blueprint ssl-endpoints
This commit is contained in:
parent
1a0f3c0a6d
commit
f94ad53471
|
@ -67,7 +67,6 @@ class cluster::haproxy (
|
|||
|
||||
Package['haproxy'] -> Class['haproxy::base']
|
||||
Class['haproxy::base'] -> Class['cluster::haproxy_ocf']
|
||||
Class['haproxy::base'] -> Haproxy::Service <||>
|
||||
|
||||
if defined(Corosync::Service['pacemaker']) {
|
||||
Corosync::Service['pacemaker'] -> Class['cluster::haproxy_ocf']
|
||||
|
|
|
@ -5,7 +5,7 @@ group :development, :unit_tests do
|
|||
gem 'rspec-core', '3.1.7', :require => false
|
||||
gem 'rspec-puppet', '~> 1.0', :require => false
|
||||
gem 'puppetlabs_spec_helper', :require => false
|
||||
gem 'puppet-lint', :require => false
|
||||
gem 'puppet-lint', '~> 0.3.2'
|
||||
gem 'simplecov', :require => false
|
||||
gem 'puppet_facts', :require => false
|
||||
gem 'json', :require => false
|
||||
|
|
|
@ -0,0 +1,144 @@
|
|||
require 'open-uri'
|
||||
require 'socket'
|
||||
require 'timeout'
|
||||
|
||||
Puppet::Type.type(:haproxy_backend_status).provide(:haproxy) do
|
||||
desc 'Wait for HAProxy backend to become online'
|
||||
|
||||
# get the raw csv value using one of the methods
|
||||
# retry if operations fails
|
||||
# @return [String]
|
||||
def csv
|
||||
@resource[:count].times do
|
||||
begin
|
||||
csv = Timeout::timeout(@resource[:step] * 3) do
|
||||
if @resource[:socket]
|
||||
debug "Get CSV from socket '#{@resource[:socket]}'"
|
||||
get_csv_unix
|
||||
else
|
||||
debug "Get CSV from url '#{@resource[:url]}'"
|
||||
get_csv_url
|
||||
end
|
||||
end
|
||||
return csv if csv
|
||||
rescue
|
||||
nil
|
||||
end
|
||||
sleep @resource[:step]
|
||||
end
|
||||
if @resource[:socket]
|
||||
raise Puppet::Error, "Could not get CSV from socket #{@resource[:socket]}"
|
||||
else
|
||||
raise Puppet::Error, "Could not get CSV from url #{@resource[:url]}"
|
||||
end
|
||||
end
|
||||
|
||||
# return the parsed stats structure
|
||||
# @return [Hash<String => Symbol>]
|
||||
def stats
|
||||
return @stats if @stats
|
||||
stats = {}
|
||||
csv.split("\n").each do |line|
|
||||
next if line.start_with? '#'
|
||||
fields = line.split(',')
|
||||
name = fields[0]
|
||||
type = fields[1]
|
||||
status = fields[17]
|
||||
next unless name and type and status
|
||||
next unless type == 'BACKEND'
|
||||
case status
|
||||
when 'UP'
|
||||
status = :up
|
||||
when 'DOWN'
|
||||
status = :down
|
||||
else
|
||||
next
|
||||
end
|
||||
stats.store name, status
|
||||
end
|
||||
@stats = stats
|
||||
end
|
||||
|
||||
# reset mnemoization of stats
|
||||
def stats_reset
|
||||
@stats = nil
|
||||
end
|
||||
|
||||
# get the current backend status value
|
||||
# @return [:up, :down, :absent, :present]
|
||||
def ensure
|
||||
debug "Call 'ensure' on HAProxy backend '#{@resource[:name]}'"
|
||||
unless exists?
|
||||
debug 'Return: absent'
|
||||
return :absent
|
||||
end
|
||||
|
||||
if [:present, :absent].include? @resource[:ensure]
|
||||
debug 'Return: present'
|
||||
return :present
|
||||
end
|
||||
|
||||
out = status
|
||||
debug "Return: #{out}"
|
||||
out
|
||||
end
|
||||
|
||||
# wait for backend status to change into specified value
|
||||
# @param value [:up, :down]
|
||||
def ensure=(value)
|
||||
debug "Waiting for HAProxy backend '#{@resource[:name]}' to change status to '#{value}'"
|
||||
@resource[:count].times do
|
||||
stats_reset
|
||||
return true if self.ensure == value
|
||||
sleep @resource[:step]
|
||||
end
|
||||
raise Puppet::Error, "Timeout waiting for HAProxy backend '#{@resource[:name]}' status to become '#{value}' after #{@resource[:count] * @resource[:step]} seconds!"
|
||||
end
|
||||
|
||||
# check if backend exists
|
||||
# @return [TrueClass, FalseClass]
|
||||
def exists?
|
||||
stats.key? @resource[:name]
|
||||
end
|
||||
|
||||
# get backend status from stats structure
|
||||
# @return [:up, :down]
|
||||
def status
|
||||
stats.fetch @resource[:name], :absent
|
||||
end
|
||||
|
||||
# get csv from HAProxy socket
|
||||
# @return [String, NilClass]
|
||||
def get_csv_unix
|
||||
csv = ''
|
||||
socket = @resource[:socket]
|
||||
begin
|
||||
UNIXSocket.open(socket) do |opened_socket|
|
||||
opened_socket.puts 'show stat'
|
||||
loop do
|
||||
line = opened_socket.gets
|
||||
break unless line
|
||||
csv << line
|
||||
end
|
||||
end
|
||||
rescue
|
||||
nil
|
||||
end
|
||||
return nil unless csv and not csv.empty?
|
||||
csv
|
||||
end
|
||||
|
||||
# download csv from url
|
||||
# @return [String, NilClass]
|
||||
def get_csv_url
|
||||
begin
|
||||
url = open(@resource[:url])
|
||||
csv = url.read
|
||||
rescue
|
||||
nil
|
||||
end
|
||||
return nil unless csv and not csv.empty?
|
||||
csv
|
||||
end
|
||||
|
||||
end
|
|
@ -0,0 +1,47 @@
|
|||
Puppet::Type.newtype(:haproxy_backend_status) do
|
||||
desc 'Wait for HAProxy backend to become online'
|
||||
|
||||
newparam(:name) do
|
||||
desc 'The name of HAProxy backend to monitor'
|
||||
isnamevar
|
||||
end
|
||||
|
||||
newparam(:url) do
|
||||
desc 'Use this url to get CSV status'
|
||||
end
|
||||
|
||||
newparam(:socket) do
|
||||
desc 'Use this socket to get CSV status'
|
||||
end
|
||||
|
||||
newproperty(:ensure) do
|
||||
desc 'Expected backend status'
|
||||
newvalues :up, :down, :present, :absent
|
||||
defaultto :up
|
||||
end
|
||||
|
||||
newparam(:count) do
|
||||
desc 'How many times try to perform check?'
|
||||
newvalues(/\d+/)
|
||||
defaultto 100
|
||||
munge do |n|
|
||||
n.to_i
|
||||
end
|
||||
end
|
||||
|
||||
newparam(:step) do
|
||||
desc 'How many seconds to wait between retries?'
|
||||
newvalues(/\d+/)
|
||||
defaultto 6
|
||||
munge do |n|
|
||||
n.to_i
|
||||
end
|
||||
end
|
||||
|
||||
def validate
|
||||
unless self[:socket].nil? ^ self[:url].nil?
|
||||
raise 'You should give either url or socket to get HAProxy status and not both!'
|
||||
end
|
||||
end
|
||||
|
||||
end
|
|
@ -55,6 +55,10 @@
|
|||
# If true, then add "cookie SERVERID" stickiness options.
|
||||
# Default false.
|
||||
#
|
||||
# [*define_backups*]
|
||||
# If true, declare all non-primary servers as backups. Use this option
|
||||
# when you need to enforce active-passive failover.
|
||||
#
|
||||
# === Examples
|
||||
#
|
||||
# Exporting the resource for a balancer member:
|
||||
|
@ -88,19 +92,28 @@
|
|||
#
|
||||
define haproxy::balancermember (
|
||||
$listening_service,
|
||||
$ports = undef,
|
||||
$server_names = $::hostname,
|
||||
$ipaddresses = $::ipaddress,
|
||||
$ensure = 'present',
|
||||
$options = '',
|
||||
$define_cookies = false
|
||||
$ports = undef,
|
||||
$server_names = $::hostname,
|
||||
$ipaddresses = $::ipaddress,
|
||||
$ensure = 'present',
|
||||
$order = '20',
|
||||
$options = '',
|
||||
$define_cookies = false,
|
||||
$define_backups = false,
|
||||
$use_include = $haproxy::params::use_include,
|
||||
) {
|
||||
|
||||
# Template uses $ipaddresses, $server_name, $ports, $option
|
||||
concat::fragment { "${listening_service}_balancermember_${name}":
|
||||
ensure => $ensure,
|
||||
order => "20-${listening_service}-01-${name}",
|
||||
target => $::haproxy::config_file,
|
||||
order => $use_include ? {
|
||||
true => "01-${name}",
|
||||
false => "${order}-${listening_service}-01-${name}",
|
||||
},
|
||||
target => $use_include ? {
|
||||
true => "/etc/haproxy/conf.d/${order}-${name}.cfg",
|
||||
false => $::haproxy::config_file,
|
||||
},
|
||||
content => template('haproxy/haproxy_balancermember.erb'),
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,83 @@
|
|||
# == Class: haproxy::base
|
||||
#
|
||||
# This class will create haproxy.cfg and populate it with global and
|
||||
# defaults configuration sections.
|
||||
#
|
||||
# === Parameters
|
||||
#
|
||||
# [*global_options*]
|
||||
# A hash of all the haproxy global options. If you want to specify more
|
||||
# than one option (i.e. multiple timeout or stats options), pass those
|
||||
# options as an array and you will get a line for each of them in the
|
||||
# resultant haproxy.cfg file.
|
||||
#
|
||||
# [*defaults_options*]
|
||||
# A hash of all the haproxy defaults options. If you want to specify more
|
||||
# than one option (i.e. multiple timeout or stats options), pass those
|
||||
# options as an array and you will get a line for each of them in the
|
||||
# resultant haproxy.cfg file.
|
||||
#
|
||||
# [*use_include*]
|
||||
# Chooses whether include directive can be used to collect haproxy
|
||||
# configuration from multiple fragment files in a conf.d directory,
|
||||
# or all fragments have to be contatenated into a single haproxy.cfg.
|
||||
#
|
||||
class haproxy::base (
|
||||
$global_options = $haproxy::params::global_options,
|
||||
$defaults_options = $haproxy::params::defaults_options,
|
||||
$use_include = $haproxy::params::use_include,
|
||||
$use_stats = $haproxy::params::use_stats,
|
||||
$stats_port = $haproxy::params::stats_port,
|
||||
$stats_ipaddresses = $haproxy::params::stats_ipaddresses,
|
||||
) inherits haproxy::params {
|
||||
include concat::setup
|
||||
|
||||
concat { '/etc/haproxy/haproxy.cfg':
|
||||
owner => '0',
|
||||
group => '0',
|
||||
mode => '0644',
|
||||
before => Service['haproxy'],
|
||||
}
|
||||
|
||||
# Simple Header
|
||||
concat::fragment { 'haproxy-header':
|
||||
target => '/etc/haproxy/haproxy.cfg',
|
||||
order => '01',
|
||||
content => "# This file managed by Puppet\n",
|
||||
}
|
||||
|
||||
# Template uses $global_options, $defaults_options
|
||||
concat::fragment { 'haproxy-base':
|
||||
target => '/etc/haproxy/haproxy.cfg',
|
||||
order => '10',
|
||||
content => template('haproxy/haproxy-base.cfg.erb'),
|
||||
}
|
||||
|
||||
if $global_options['chroot'] {
|
||||
file { $global_options['chroot']:
|
||||
ensure => directory,
|
||||
}
|
||||
}
|
||||
|
||||
if $use_stats {
|
||||
concat::fragment { 'haproxy-stats' :
|
||||
target => '/etc/haproxy/haproxy.cfg',
|
||||
order => '90',
|
||||
content => template('haproxy/haproxy-stats.cfg.erb'),
|
||||
}
|
||||
}
|
||||
|
||||
if $use_include {
|
||||
concat::fragment { 'haproxy-include':
|
||||
target => '/etc/haproxy/haproxy.cfg',
|
||||
order => '99',
|
||||
content => "\ninclude conf.d/*.cfg\n",
|
||||
}
|
||||
|
||||
file { '/etc/haproxy/conf.d':
|
||||
ensure => 'directory',
|
||||
owner => '0',
|
||||
group => '0',
|
||||
}
|
||||
}
|
||||
}
|
|
@ -81,6 +81,7 @@ define haproxy::listen (
|
|||
$bind = undef,
|
||||
$mode = undef,
|
||||
$collect_exported = true,
|
||||
$order = '20',
|
||||
$options = {
|
||||
'option' => [
|
||||
'tcplog',
|
||||
|
@ -88,6 +89,7 @@ define haproxy::listen (
|
|||
],
|
||||
'balance' => 'roundrobin'
|
||||
},
|
||||
$use_include = $haproxy::params::use_include,
|
||||
# Deprecated
|
||||
$bind_options = '',
|
||||
) {
|
||||
|
@ -109,10 +111,25 @@ define haproxy::listen (
|
|||
fail("An haproxy::backend resource was discovered with the same name (${name}) which is not supported")
|
||||
}
|
||||
|
||||
if $use_include {
|
||||
$target = "/etc/haproxy/conf.d/${order}-${name}.cfg"
|
||||
$fragment_order = '00'
|
||||
|
||||
concat { $target:
|
||||
owner => '0',
|
||||
group => '0',
|
||||
mode => '0644',
|
||||
}
|
||||
|
||||
} else {
|
||||
$target = '/etc/haproxy/haproxy.conf'
|
||||
$fragment_order = "${order}-${name}-00"
|
||||
}
|
||||
|
||||
# Template uses: $name, $ipaddress, $ports, $options
|
||||
concat::fragment { "${name}_listen_block":
|
||||
order => "20-${name}-00",
|
||||
target => $::haproxy::config_file,
|
||||
order => $fragment_order,
|
||||
target => $target,
|
||||
content => template('haproxy/haproxy_listen_block.erb'),
|
||||
}
|
||||
|
||||
|
|
|
@ -65,4 +65,8 @@ class haproxy::params {
|
|||
}
|
||||
default: { fail("The ${::osfamily} operating system is not supported with the haproxy module") }
|
||||
}
|
||||
$use_include = false
|
||||
$use_stats = true
|
||||
$stats_port = '10000'
|
||||
$stats_ipaddresses = ['127.0.0.1']
|
||||
}
|
||||
|
|
|
@ -0,0 +1,12 @@
|
|||
|
||||
listen Stats
|
||||
<% Array(@stats_ipaddresses).uniq.each do |ip| -%>
|
||||
bind <%= ip %>:<%= @stats_port %>
|
||||
<% end -%>
|
||||
mode http
|
||||
stats enable
|
||||
stats uri /
|
||||
stats refresh 5s
|
||||
stats show-node
|
||||
stats show-legends
|
||||
stats hide-version
|
|
@ -1,9 +1,9 @@
|
|||
<% Array(@ipaddresses).zip(Array(@server_names)).each do |ipaddress,host| -%>
|
||||
<% if @ports -%>
|
||||
<%- Array(@ports).each do |port| -%>
|
||||
server <%= host %> <%= ipaddress %>:<%= port %><%= if @define_cookies then " cookie " + host end %> <%= Array(@options).sort.join(" ") %>
|
||||
server <%= host %> <%= ipaddress %>:<%= port %><%= if @define_cookies then " cookie " + host end %> <%= if @define_backups and @server_names.first != host then "backup" end -%> <%= Array(@options).sort.join(" ") %>
|
||||
<%- end -%>
|
||||
<% else -%>
|
||||
server <%= host %> <%= ipaddress %><%= if @define_cookies then " cookie " + host end %> <%= Array(@options).sort.join(" ") %>
|
||||
server <%= host %> <%= ipaddress %><%= if @define_cookies then " cookie " + host end %> <%= if @define_backups and @server_names.first != host then "backup" end -%> <%= Array(@options).sort.join(" ") %>
|
||||
<%- end -%>
|
||||
<% end -%>
|
||||
|
|
|
@ -40,11 +40,12 @@ define openstack::ha::haproxy_service (
|
|||
}
|
||||
|
||||
haproxy::listen { $name:
|
||||
order => $order,
|
||||
ipaddress => $virtual_ips,
|
||||
ports => $listen_port,
|
||||
options => $haproxy_config_options,
|
||||
mode => $mode,
|
||||
order => $order,
|
||||
ipaddress => $virtual_ips,
|
||||
ports => $listen_port,
|
||||
options => $haproxy_config_options,
|
||||
mode => $mode,
|
||||
use_include => true,
|
||||
}
|
||||
|
||||
haproxy::balancermember { $name:
|
||||
|
@ -56,6 +57,7 @@ define openstack::ha::haproxy_service (
|
|||
options => $balancermember_options,
|
||||
define_cookies => $define_cookies,
|
||||
define_backups => $define_backups,
|
||||
use_include => true,
|
||||
}
|
||||
|
||||
# Dirty hack, due Puppet can't send notify between stages
|
||||
|
|
Loading…
Reference in New Issue