@ -35,6 +35,14 @@ options:
- Name of the HAProxy backend pool .
- Name of the HAProxy backend pool .
required : false
required : false
default : auto - detected
default : auto - detected
drain :
description :
- Wait until the server has no active connections or until the timeout
determined by wait_interval and wait_retries is reached . Continue only
after the status changes to ' MAINT ' . This overrides the
shutdown_sessions option .
default : false
version_added : " 2.4 "
host :
host :
description :
description :
- Name of the backend host to change .
- Name of the backend host to change .
@ -44,7 +52,8 @@ options:
description :
description :
- When disabling a server , immediately terminate all the sessions attached
- When disabling a server , immediately terminate all the sessions attached
to the specified server . This can be used to terminate long - running
to the specified server . This can be used to terminate long - running
sessions after a server is put into maintenance mode .
sessions after a server is put into maintenance mode . Overridden by the
drain option .
required : false
required : false
default : false
default : false
socket :
socket :
@ -122,6 +131,19 @@ EXAMPLES = '''
backend : www
backend : www
wait : yes
wait : yes
# Place server in drain mode, providing a socket file. Then check the server's
# status every minute to see if it changes to maintenance mode, continuing if it
# does in an hour and failing otherwise.
- haproxy :
state : disabled
host : ' {{ inventory_hostname }} '
socket : / var / run / haproxy . sock
backend : www
wait : yes
drain : yes
wait_interval : 1
wait_retries : 60
# 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 :
- haproxy :
state : disabled
state : disabled
@ -219,6 +241,7 @@ class HAProxy(object):
self . wait = self . module . params [ ' wait ' ]
self . wait = self . module . params [ ' wait ' ]
self . wait_retries = self . module . params [ ' wait_retries ' ]
self . wait_retries = self . module . params [ ' wait_retries ' ]
self . wait_interval = self . module . params [ ' wait_interval ' ]
self . wait_interval = self . module . params [ ' wait_interval ' ]
self . drain = self . module . params [ ' drain ' ]
self . command_results = { }
self . command_results = { }
def execute ( self , cmd , timeout = 200 , capture_output = True ) :
def execute ( self , cmd , timeout = 200 , capture_output = True ) :
@ -308,7 +331,7 @@ class HAProxy(object):
r = csv . DictReader ( data . splitlines ( ) )
r = csv . DictReader ( data . splitlines ( ) )
state = tuple (
state = tuple (
map (
map (
lambda d : { ' status ' : d [ ' status ' ] , ' weight ' : d [ ' weight ' ] },
lambda d : { ' status ' : d [ ' status ' ] , ' weight ' : d [ ' weight ' ] , ' scur ' : d [ ' scur ' ] },
filter ( lambda d : ( pxname is None or d [ ' pxname ' ] == pxname ) and d [ ' svname ' ] == svname , r )
filter ( lambda d : ( pxname is None or d [ ' pxname ' ] == pxname ) and d [ ' svname ' ] == svname , r )
)
)
)
)
@ -326,7 +349,8 @@ class HAProxy(object):
# We can assume there will only be 1 element in state because both svname and pxname are always set when we get here
# We can assume there will only be 1 element in state because both svname and pxname are always set when we get here
if state [ 0 ] [ ' status ' ] == status :
if state [ 0 ] [ ' status ' ] == status :
return True
if not self . drain or ( state [ 0 ] [ ' scur ' ] == ' 0 ' and state == ' MAINT ' ) :
return True
else :
else :
time . sleep ( self . wait_interval )
time . sleep ( self . wait_interval )
@ -354,7 +378,7 @@ 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 ):
def drain ( self , host , backend , status = ' DRAIN ' ):
"""
"""
Drain action , sets the server to DRAIN mode .
Drain action , sets the server to DRAIN mode .
In this mode mode , the server will not accept any new connections
In this mode mode , the server will not accept any new connections
@ -365,7 +389,7 @@ class HAProxy(object):
# check if haproxy version suppots DRAIN state (starting with 1.5)
# check if haproxy version suppots DRAIN state (starting with 1.5)
if haproxy_version and ( 1 , 5 ) < = haproxy_version :
if haproxy_version and ( 1 , 5 ) < = haproxy_version :
cmd = " set server $pxname/$svname state drain "
cmd = " set server $pxname/$svname state drain "
self . execute_for_backends ( cmd , backend , host , ' DRAIN ' )
self . execute_for_backends ( cmd , backend , host , status )
def act ( self ) :
def act ( self ) :
"""
"""
@ -378,6 +402,8 @@ class HAProxy(object):
# toggle enable/disbale server
# toggle enable/disbale server
if self . state == ' enabled ' :
if self . state == ' enabled ' :
self . enabled ( self . host , self . backend , self . weight )
self . enabled ( self . host , self . backend , self . weight )
elif self . state == ' disabled ' and self . drain :
self . drain ( self . host , self . backend , status = ' MAINT ' )
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 ' :
elif self . state == ' drain ' :
@ -413,6 +439,7 @@ def main():
wait = dict ( required = False , default = False , type = ' bool ' ) ,
wait = dict ( required = False , default = False , type = ' bool ' ) ,
wait_retries = dict ( required = False , default = WAIT_RETRIES , type = ' int ' ) ,
wait_retries = dict ( required = False , default = WAIT_RETRIES , type = ' int ' ) ,
wait_interval = dict ( required = False , default = WAIT_INTERVAL , type = ' int ' ) ,
wait_interval = dict ( required = False , default = WAIT_INTERVAL , type = ' int ' ) ,
drain = dict ( default = False , type = ' bool ' ) ,
) ,
) ,
)
)