haproxy: Add new drained state (#25115)

This commit is contained in:
zzaa 2017-07-04 11:33:32 +03:00 committed by René Moser
parent 996281d748
commit df0864d801

View file

@ -30,10 +30,10 @@ version_added: "1.9"
short_description: Enable, disable, and set weights for HAProxy backend servers using socket commands.
author: "Ravi Bhure (@ravibhure)"
description:
- Enable, disable, and set weights for HAProxy backend servers using socket
- Enable, disable, drain and set weights for HAProxy backend servers using socket
commands.
notes:
- Enable and disable commands are restricted and can only be issued on
- Enable, disable and drain commands are restricted and can only be issued on
sockets configured for level 'admin'. For example, you can add the line
'stats socket /var/run/haproxy.sock level admin' to the general section of
haproxy.cfg. See U(http://haproxy.1wt.eu/download/1.5/doc/configuration.txt).
@ -65,9 +65,11 @@ options:
state:
description:
- Desired state of the provided backend host.
Note that "drain" state is supported only by HAProxy version 1.5 or later,
if used on versions < 1.5, it will be ignored.
required: true
default: null
choices: [ "enabled", "disabled" ]
choices: [ "enabled", "disabled", "drain" ]
fail_on_not_found:
description:
- Fail whenever trying to enable/disable a backend host that does not exist
@ -76,8 +78,8 @@ options:
version_added: "2.2"
wait:
description:
- Wait until the server reports a status of 'UP' when `state=enabled`, or
status of 'MAINT' when `state=disabled`.
- Wait until the server reports a status of 'UP' when `state=enabled`,
status of 'MAINT' when `state=disabled` or status of 'DRAIN' when `state=drain`
required: false
default: false
version_added: "2.0"
@ -173,6 +175,13 @@ EXAMPLES = '''
socket: /var/run/haproxy.sock
weight: 10
backend: www
# set the server in 'www' backend pool to drain mode
- haproxy:
state: drain
host: '{{ inventory_hostname }}'
socket: /var/run/haproxy.sock
backend: www
'''
import socket
@ -183,7 +192,7 @@ from string import Template
DEFAULT_SOCKET_LOCATION = "/var/run/haproxy.sock"
RECV_SIZE = 1024
ACTION_CHOICES = ['enabled', 'disabled']
ACTION_CHOICES = ['enabled', 'disabled', 'drain']
WAIT_RETRIES = 25
WAIT_INTERVAL = 5
@ -259,6 +268,22 @@ class HAProxy(object):
r = csv.DictReader(data.splitlines())
return tuple(map(lambda d: d['pxname'], filter(lambda d: d['svname'] == 'BACKEND', r)))
def discover_version(self):
"""
Attempt to extract the haproxy version.
Return a tuple containing major and minor version.
"""
data = self.execute('show info', 200, False)
lines = data.splitlines()
line = [x for x in lines if 'Version:' in x]
try:
version_values = line[0].partition(':')[2].strip().split('.', 3)
version = (int(version_values[0]), int(version_values[1]))
except (ValueError, TypeError, IndexError):
version = None
return version
def execute_for_backends(self, cmd, pxname, svname, wait_for_status=None):
"""
Run some command on the specified backends. If no backends are provided they will
@ -336,6 +361,19 @@ class HAProxy(object):
cmd += "; shutdown sessions server $pxname/$svname"
self.execute_for_backends(cmd, backend, host, 'MAINT')
def drain(self, host, backend):
"""
Drain action, sets the server to DRAIN mode.
In this mode mode, the server will not accept any new connections
other than those that are accepted via persistence.
"""
haproxy_version = self.discover_version()
# check if haproxy version suppots DRAIN state (starting with 1.5)
if haproxy_version and (1, 5) <= haproxy_version:
cmd = "set server $pxname/$svname state drain"
self.execute_for_backends(cmd, backend, host, 'DRAIN')
def act(self):
"""
Figure out what you want to do from ansible, and then do it.
@ -349,6 +387,8 @@ class HAProxy(object):
self.enabled(self.host, self.backend, self.weight)
elif self.state == 'disabled':
self.disabled(self.host, self.backend, self.shutdown_sessions)
elif self.state == 'drain':
self.drain(self.host, self.backend)
else:
self.module.fail_json(msg="unknown state specified: '%s'" % self.state)