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

Add new drained state #25115

Merged
merged 7 commits into from
Jul 4, 2017
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
52 changes: 46 additions & 6 deletions lib/ansible/modules/net_tools/haproxy.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,10 +30,10 @@
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).
Expand Down Expand Up @@ -65,9 +65,11 @@
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
Expand All @@ -76,8 +78,8 @@
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"
Expand Down Expand Up @@ -173,6 +175,13 @@
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
Expand All @@ -183,7 +192,7 @@

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

Expand Down Expand Up @@ -259,6 +268,22 @@ def discover_all_backends(self):
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
Expand Down Expand Up @@ -336,6 +361,19 @@ def disabled(self, host, backend, shutdown_sessions):
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.
Expand All @@ -349,6 +387,8 @@ def act(self):
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)

Expand Down