mirror of
https://github.com/ansible-collections/community.general.git
synced 2025-04-25 11:51:26 -07:00
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.
|
short_description: Enable, disable, and set weights for HAProxy backend servers using socket commands.
|
||||||
author: "Ravi Bhure (@ravibhure)"
|
author: "Ravi Bhure (@ravibhure)"
|
||||||
description:
|
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.
|
commands.
|
||||||
notes:
|
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
|
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
|
'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).
|
haproxy.cfg. See U(http://haproxy.1wt.eu/download/1.5/doc/configuration.txt).
|
||||||
|
@ -65,9 +65,11 @@ options:
|
||||||
state:
|
state:
|
||||||
description:
|
description:
|
||||||
- Desired state of the provided backend host.
|
- 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
|
required: true
|
||||||
default: null
|
default: null
|
||||||
choices: [ "enabled", "disabled" ]
|
choices: [ "enabled", "disabled", "drain" ]
|
||||||
fail_on_not_found:
|
fail_on_not_found:
|
||||||
description:
|
description:
|
||||||
- Fail whenever trying to enable/disable a backend host that does not exist
|
- Fail whenever trying to enable/disable a backend host that does not exist
|
||||||
|
@ -76,8 +78,8 @@ options:
|
||||||
version_added: "2.2"
|
version_added: "2.2"
|
||||||
wait:
|
wait:
|
||||||
description:
|
description:
|
||||||
- Wait until the server reports a status of 'UP' when `state=enabled`, or
|
- Wait until the server reports a status of 'UP' when `state=enabled`,
|
||||||
status of 'MAINT' when `state=disabled`.
|
status of 'MAINT' when `state=disabled` or status of 'DRAIN' when `state=drain`
|
||||||
required: false
|
required: false
|
||||||
default: false
|
default: false
|
||||||
version_added: "2.0"
|
version_added: "2.0"
|
||||||
|
@ -173,6 +175,13 @@ EXAMPLES = '''
|
||||||
socket: /var/run/haproxy.sock
|
socket: /var/run/haproxy.sock
|
||||||
weight: 10
|
weight: 10
|
||||||
backend: www
|
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
|
import socket
|
||||||
|
@ -183,7 +192,7 @@ from string import Template
|
||||||
|
|
||||||
DEFAULT_SOCKET_LOCATION = "/var/run/haproxy.sock"
|
DEFAULT_SOCKET_LOCATION = "/var/run/haproxy.sock"
|
||||||
RECV_SIZE = 1024
|
RECV_SIZE = 1024
|
||||||
ACTION_CHOICES = ['enabled', 'disabled']
|
ACTION_CHOICES = ['enabled', 'disabled', 'drain']
|
||||||
WAIT_RETRIES = 25
|
WAIT_RETRIES = 25
|
||||||
WAIT_INTERVAL = 5
|
WAIT_INTERVAL = 5
|
||||||
|
|
||||||
|
@ -259,6 +268,22 @@ class HAProxy(object):
|
||||||
r = csv.DictReader(data.splitlines())
|
r = csv.DictReader(data.splitlines())
|
||||||
return tuple(map(lambda d: d['pxname'], filter(lambda d: d['svname'] == 'BACKEND', r)))
|
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):
|
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
|
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"
|
cmd += "; shutdown sessions server $pxname/$svname"
|
||||||
self.execute_for_backends(cmd, backend, host, 'MAINT')
|
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):
|
def act(self):
|
||||||
"""
|
"""
|
||||||
Figure out what you want to do from ansible, and then do it.
|
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)
|
self.enabled(self.host, self.backend, self.weight)
|
||||||
elif self.state == 'disabled':
|
elif self.state == 'disabled':
|
||||||
self.disabled(self.host, self.backend, self.shutdown_sessions)
|
self.disabled(self.host, self.backend, self.shutdown_sessions)
|
||||||
|
elif self.state == 'drain':
|
||||||
|
self.drain(self.host, self.backend)
|
||||||
else:
|
else:
|
||||||
self.module.fail_json(msg="unknown state specified: '%s'" % self.state)
|
self.module.fail_json(msg="unknown state specified: '%s'" % self.state)
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue