commit
bd177bcb62
1 changed files with 72 additions and 3 deletions
|
@ -68,6 +68,24 @@ options:
|
||||||
- When disabling server, immediately terminate all the sessions attached to the specified server. This can be used to terminate long-running sessions after a server is put into maintenance mode, for instance.
|
- When disabling server, immediately terminate all the sessions attached to the specified server. This can be used to terminate long-running sessions after a server is put into maintenance mode, for instance.
|
||||||
required: false
|
required: false
|
||||||
default: false
|
default: false
|
||||||
|
wait:
|
||||||
|
description:
|
||||||
|
- Wait until the server reports a status of 'UP' when state=enabled, or status of 'MAINT' when state=disabled
|
||||||
|
required: false
|
||||||
|
default: false
|
||||||
|
version_added: "2.0"
|
||||||
|
wait_retries:
|
||||||
|
description:
|
||||||
|
- number of times to check for status after changing the state
|
||||||
|
required: false
|
||||||
|
default: 20
|
||||||
|
version_added: "2.0"
|
||||||
|
wait_interval:
|
||||||
|
description:
|
||||||
|
- number of seconds to wait between retries
|
||||||
|
required: false
|
||||||
|
default: 1
|
||||||
|
version_added: "2.0"
|
||||||
'''
|
'''
|
||||||
|
|
||||||
EXAMPLES = '''
|
EXAMPLES = '''
|
||||||
|
@ -82,12 +100,21 @@ examples:
|
||||||
# disable server, provide socket file
|
# disable server, provide socket file
|
||||||
- haproxy: state=disabled host={{ inventory_hostname }} socket=/var/run/haproxy.sock backend=www
|
- haproxy: state=disabled host={{ inventory_hostname }} socket=/var/run/haproxy.sock backend=www
|
||||||
|
|
||||||
|
# disable server, provide socket file, wait until status reports in maintenance
|
||||||
|
- haproxy: state=disabled host={{ inventory_hostname }} socket=/var/run/haproxy.sock backend=www wait=yes
|
||||||
|
|
||||||
# disable backend server in 'www' backend pool and drop open sessions to it
|
# disable backend server in 'www' backend pool and drop open sessions to it
|
||||||
- haproxy: state=disabled host={{ inventory_hostname }} backend=www socket=/var/run/haproxy.sock shutdown_sessions=true
|
- haproxy: state=disabled host={{ inventory_hostname }} backend=www socket=/var/run/haproxy.sock shutdown_sessions=true
|
||||||
|
|
||||||
# enable server in 'www' backend pool
|
# enable server in 'www' backend pool
|
||||||
- haproxy: state=enabled host={{ inventory_hostname }} backend=www
|
- haproxy: state=enabled host={{ inventory_hostname }} backend=www
|
||||||
|
|
||||||
|
# enable server in 'www' backend pool wait until healthy
|
||||||
|
- haproxy: state=enabled host={{ inventory_hostname }} backend=www wait=yes
|
||||||
|
|
||||||
|
# enable server in 'www' backend pool wait until healthy. Retry 10 times with intervals of 5 seconds to retrieve the health
|
||||||
|
- haproxy: state=enabled host={{ inventory_hostname }} backend=www wait=yes wait_retries=10 wait_interval=5
|
||||||
|
|
||||||
# enable server in 'www' backend pool with change server(s) weight
|
# enable server in 'www' backend pool with change server(s) weight
|
||||||
- haproxy: state=enabled host={{ inventory_hostname }} socket=/var/run/haproxy.sock weight=10 backend=www
|
- haproxy: state=enabled host={{ inventory_hostname }} socket=/var/run/haproxy.sock weight=10 backend=www
|
||||||
|
|
||||||
|
@ -95,11 +122,15 @@ author: "Ravi Bhure (@ravibhure)"
|
||||||
'''
|
'''
|
||||||
|
|
||||||
import socket
|
import socket
|
||||||
|
import csv
|
||||||
|
import time
|
||||||
|
|
||||||
|
|
||||||
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']
|
||||||
|
WAIT_RETRIES=20
|
||||||
|
WAIT_INTERVAL=1
|
||||||
|
|
||||||
######################################################################
|
######################################################################
|
||||||
class TimeoutException(Exception):
|
class TimeoutException(Exception):
|
||||||
|
@ -126,10 +157,12 @@ class HAProxy(object):
|
||||||
self.weight = self.module.params['weight']
|
self.weight = self.module.params['weight']
|
||||||
self.socket = self.module.params['socket']
|
self.socket = self.module.params['socket']
|
||||||
self.shutdown_sessions = self.module.params['shutdown_sessions']
|
self.shutdown_sessions = self.module.params['shutdown_sessions']
|
||||||
|
self.wait = self.module.params['wait']
|
||||||
|
self.wait_retries = self.module.params['wait_retries']
|
||||||
|
self.wait_interval = self.module.params['wait_interval']
|
||||||
self.command_results = []
|
self.command_results = []
|
||||||
|
|
||||||
def execute(self, cmd, timeout=200):
|
def execute(self, cmd, timeout=200, capture_output=True):
|
||||||
"""
|
"""
|
||||||
Executes a HAProxy command by sending a message to a HAProxy's local
|
Executes a HAProxy command by sending a message to a HAProxy's local
|
||||||
UNIX socket and waiting up to 'timeout' milliseconds for the response.
|
UNIX socket and waiting up to 'timeout' milliseconds for the response.
|
||||||
|
@ -144,10 +177,35 @@ class HAProxy(object):
|
||||||
while buf:
|
while buf:
|
||||||
result += buf
|
result += buf
|
||||||
buf = self.client.recv(RECV_SIZE)
|
buf = self.client.recv(RECV_SIZE)
|
||||||
self.command_results = result.strip()
|
if capture_output:
|
||||||
|
self.command_results = result.strip()
|
||||||
self.client.close()
|
self.client.close()
|
||||||
return result
|
return result
|
||||||
|
|
||||||
|
def wait_until_status(self, pxname, svname, status):
|
||||||
|
"""
|
||||||
|
Wait for a service to reach the specified status. Try RETRIES times
|
||||||
|
with INTERVAL seconds of sleep in between. If the service has not reached
|
||||||
|
the expected status in that time, the module will fail. If the service was
|
||||||
|
not found, the module will fail.
|
||||||
|
"""
|
||||||
|
for i in range(1, self.wait_retries):
|
||||||
|
data = self.execute('show stat', 200, False).lstrip('# ')
|
||||||
|
r = csv.DictReader(data.splitlines())
|
||||||
|
found = False
|
||||||
|
for row in r:
|
||||||
|
if row['pxname'] == pxname and row['svname'] == svname:
|
||||||
|
found = True
|
||||||
|
if row['status'] == status:
|
||||||
|
return True;
|
||||||
|
else:
|
||||||
|
time.sleep(self.wait_interval)
|
||||||
|
|
||||||
|
if not found:
|
||||||
|
self.module.fail_json(msg="unable to find server %s/%s" % (pxname, svname))
|
||||||
|
|
||||||
|
self.module.fail_json(msg="server %s/%s not status '%s' after %d retries. Aborting." % (pxname, svname, status, self.wait_retries))
|
||||||
|
|
||||||
def enabled(self, host, backend, weight):
|
def enabled(self, host, backend, weight):
|
||||||
"""
|
"""
|
||||||
Enabled action, marks server to UP and checks are re-enabled,
|
Enabled action, marks server to UP and checks are re-enabled,
|
||||||
|
@ -170,6 +228,8 @@ class HAProxy(object):
|
||||||
if weight:
|
if weight:
|
||||||
cmd += "; set weight %s/%s %s" % (pxname, svname, weight)
|
cmd += "; set weight %s/%s %s" % (pxname, svname, weight)
|
||||||
self.execute(cmd)
|
self.execute(cmd)
|
||||||
|
if self.wait:
|
||||||
|
self.wait_until_status(pxname, svname, 'UP')
|
||||||
|
|
||||||
else:
|
else:
|
||||||
pxname = backend
|
pxname = backend
|
||||||
|
@ -177,6 +237,8 @@ class HAProxy(object):
|
||||||
if weight:
|
if weight:
|
||||||
cmd += "; set weight %s/%s %s" % (pxname, svname, weight)
|
cmd += "; set weight %s/%s %s" % (pxname, svname, weight)
|
||||||
self.execute(cmd)
|
self.execute(cmd)
|
||||||
|
if self.wait:
|
||||||
|
self.wait_until_status(pxname, svname, 'UP')
|
||||||
|
|
||||||
def disabled(self, host, backend, shutdown_sessions):
|
def disabled(self, host, backend, shutdown_sessions):
|
||||||
"""
|
"""
|
||||||
|
@ -200,6 +262,8 @@ class HAProxy(object):
|
||||||
if shutdown_sessions:
|
if shutdown_sessions:
|
||||||
cmd += "; shutdown sessions server %s/%s" % (pxname, svname)
|
cmd += "; shutdown sessions server %s/%s" % (pxname, svname)
|
||||||
self.execute(cmd)
|
self.execute(cmd)
|
||||||
|
if self.wait:
|
||||||
|
self.wait_until_status(pxname, svname, 'MAINT')
|
||||||
|
|
||||||
else:
|
else:
|
||||||
pxname = backend
|
pxname = backend
|
||||||
|
@ -207,6 +271,8 @@ class HAProxy(object):
|
||||||
if shutdown_sessions:
|
if shutdown_sessions:
|
||||||
cmd += "; shutdown sessions server %s/%s" % (pxname, svname)
|
cmd += "; shutdown sessions server %s/%s" % (pxname, svname)
|
||||||
self.execute(cmd)
|
self.execute(cmd)
|
||||||
|
if self.wait:
|
||||||
|
self.wait_until_status(pxname, svname, 'MAINT')
|
||||||
|
|
||||||
def act(self):
|
def act(self):
|
||||||
"""
|
"""
|
||||||
|
@ -236,6 +302,9 @@ def main():
|
||||||
weight=dict(required=False, default=None),
|
weight=dict(required=False, default=None),
|
||||||
socket = dict(required=False, default=DEFAULT_SOCKET_LOCATION),
|
socket = dict(required=False, default=DEFAULT_SOCKET_LOCATION),
|
||||||
shutdown_sessions=dict(required=False, default=False),
|
shutdown_sessions=dict(required=False, default=False),
|
||||||
|
wait=dict(required=False, default=False),
|
||||||
|
wait_retries=dict(required=False, default=WAIT_RETRIES),
|
||||||
|
wait_interval=dict(required=False, default=WAIT_INTERVAL),
|
||||||
),
|
),
|
||||||
|
|
||||||
)
|
)
|
||||||
|
|
Loading…
Reference in a new issue