haproxy: Add new drained state (#25115)
This commit is contained in:
parent
996281d748
commit
df0864d801
1 changed files with 46 additions and 6 deletions
|
@ -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)
|
||||
|
||||
|
|
Loading…
Reference in a new issue