@ -23,15 +23,15 @@ DOCUMENTATION = '''
module : bigip_pool
module : bigip_pool
short_description : " Manages F5 BIG-IP LTM pools "
short_description : " Manages F5 BIG-IP LTM pools "
description :
description :
- " Manages F5 BIG-IP LTM pools via iControl SOAP API "
- Manages F5 BIG - IP LTM pools via iControl SOAP API
version_added : " 1.2 "
version_added : 1.2
author :
author :
- Matt Hite ( @mhite )
- Matt Hite ( @mhite )
- Tim Rupp ( @caphrim007 )
- Tim Rupp ( @caphrim007 )
notes :
notes :
- " Requires BIG-IP software version >= 11 "
- Requires BIG - IP software version > = 11
- " F5 developed module ' bigsuds ' required (see http://devcentral.f5.com) "
- F5 developed module ' bigsuds ' required ( see http : / / devcentral . f5 . com )
- " Best run as a local_action in your playbook "
- Best run as a local_action in your playbook
requirements :
requirements :
- bigsuds
- bigsuds
options :
options :
@ -69,14 +69,18 @@ options:
validate on python > = 2.7 .9 and never validate on python < = 2.7 .8
validate on python > = 2.7 .9 and never validate on python < = 2.7 .8
required : false
required : false
default : ' yes '
default : ' yes '
choices : [ ' yes ' , ' no ' ]
choices :
version_added : 1.9 .1
- yes
- no
version_added : 2.0
state :
state :
description :
description :
- Pool / pool member state
- Pool / pool member state
required : false
required : false
default : present
default : present
choices : [ ' present ' , ' absent ' ]
choices :
- present
- absent
aliases : [ ]
aliases : [ ]
name :
name :
description :
description :
@ -84,7 +88,8 @@ options:
required : true
required : true
default : null
default : null
choices : [ ]
choices : [ ]
aliases : [ ' pool ' ]
aliases :
- pool
partition :
partition :
description :
description :
- Partition of pool / pool member
- Partition of pool / pool member
@ -98,16 +103,27 @@ options:
version_added : " 1.3 "
version_added : " 1.3 "
required : False
required : False
default : ' round_robin '
default : ' round_robin '
choices : [ ' round_robin ' , ' ratio_member ' , ' least_connection_member ' ,
choices :
' observed_member ' , ' predictive_member ' , ' ratio_node_address ' ,
- round_robin
' least_connection_node_address ' , ' fastest_node_address ' ,
- ratio_member
' observed_node_address ' , ' predictive_node_address ' ,
- least_connection_member
' dynamic_ratio ' , ' fastest_app_response ' , ' least_sessions ' ,
- observed_member
' dynamic_ratio_member ' , ' l3_addr ' ,
- predictive_member
' weighted_least_connection_member ' ,
- ratio_node_address
' weighted_least_connection_node_address ' ,
- least_connection_node_address
' ratio_session ' , ' ratio_least_connection_member ' ,
- fastest_node_address
' ratio_least_connection_node_address ' ]
- observed_node_address
- predictive_node_address
- dynamic_ratio
- fastest_app_response
- least_sessions
- dynamic_ratio_member
- l3_addr
- weighted_least_connection_member
- weighted_least_connection_node_address
- ratio_session
- ratio_least_connection_member
- ratio_least_connection_node_address
aliases : [ ]
aliases : [ ]
monitor_type :
monitor_type :
description :
description :
@ -135,7 +151,8 @@ options:
aliases : [ ]
aliases : [ ]
slow_ramp_time :
slow_ramp_time :
description :
description :
- Sets the ramp - up time ( in seconds ) to gradually ramp up the load on newly added or freshly detected up pool members
- Sets the ramp - up time ( in seconds ) to gradually ramp up the load on
newly added or freshly detected up pool members
version_added : " 1.3 "
version_added : " 1.3 "
required : False
required : False
default : null
default : null
@ -143,7 +160,8 @@ options:
aliases : [ ]
aliases : [ ]
reselect_tries :
reselect_tries :
description :
description :
- Sets the number of times the system tries to contact a pool member after a passive failure
- Sets the number of times the system tries to contact a pool member
after a passive failure
version_added : " 2.2 "
version_added : " 2.2 "
required : False
required : False
default : null
default : null
@ -155,7 +173,11 @@ options:
version_added : " 1.3 "
version_added : " 1.3 "
required : False
required : False
default : null
default : null
choices : [ ' none ' , ' reset ' , ' drop ' , ' reselect ' ]
choices :
- none
- reset
- drop
- reselect
aliases : [ ]
aliases : [ ]
host :
host :
description :
description :
@ -163,10 +185,11 @@ options:
required : False
required : False
default : null
default : null
choices : [ ]
choices : [ ]
aliases : [ ' address ' ]
aliases :
- address
port :
port :
description :
description :
- " Pool member port "
- Pool member port
required : False
required : False
default : null
default : null
choices : [ ]
choices : [ ]
@ -174,84 +197,71 @@ options:
'''
'''
EXAMPLES = '''
EXAMPLES = '''
## playbook task examples:
- - -
# file bigip-test.yml
# ...
- hosts : localhost
tasks :
- name : Create pool
- name : Create pool
local_action : >
bigip_pool :
bigip_pool
server : " lb.mydomain.com "
server= lb . mydomain . com
user : " admin "
user= admin
password : " secret "
password= mysecret
state : " present "
state= present
name : " my-pool "
name= matthite - pool
partition : " Common "
partition= matthite
lb_method: " least_connection_member "
lb_method= least_connection_member
slow_ramp_time: 120
slow_ramp_time = 120
delegate_to : localhost
- name : Modify load balancer method
- name : Modify load balancer method
local_action : >
bigip_pool :
bigip_pool
server : " lb.mydomain.com "
server = lb . mydomain . com
user : " admin "
user = admin
password : " secret "
password = mysecret
state : " present "
state = present
name : " my-pool "
name = matthite - pool
partition : " Common "
partition = matthite
lb_method : " round_robin "
lb_method = round_robin
- hosts : bigip - test
tasks :
- name : Add pool member
- name : Add pool member
local_action : >
bigip_pool :
bigip_pool
server : " lb.mydomain.com "
server = lb . mydomain . com
user : " admin "
user = admin
password : " secret "
password = mysecret
state : " present "
state = present
name : " my-pool "
name = matthite - pool
partition : " Common "
partition = matthite
host : " {{ ansible_default_ipv4[ " address " ] }} "
host = " {{ ansible_default_ipv4[ " address " ] }} "
port : 80
port = 80
- name : Remove pool member from pool
- name : Remove pool member from pool
local_action : >
bigip_pool :
bigip_pool
server : " lb.mydomain.com "
server = lb . mydomain . com
user : " admin "
user = admin
password : " secret "
password = mysecret
state : " absent "
state = absent
name : " my-pool "
name = matthite - pool
partition : " Common "
partition = matthite
host : " {{ ansible_default_ipv4[ " address " ] }} "
host = " {{ ansible_default_ipv4[ " address " ] }} "
port : 80
port = 80
- hosts : localhost
tasks :
- name : Delete pool
- name : Delete pool
local_action : >
bigip_pool :
bigip_pool
server : " lb.mydomain.com "
server= lb . mydomain . com
user: " admin "
user= admin
password: " secret "
password= mysecret
state: " absent "
state= absent
name: " my-pool "
name= matthite - pool
partition: " Common "
partition = matthite
'''
RETURN = '''
'''
'''
def pool_exists ( api , pool ) :
def pool_exists ( api , pool ) :
# hack to determine if pool exists
# hack to determine if pool exists
result = False
result = False
try :
try :
api . LocalLB . Pool . get_object_status ( pool_names = [ pool ] )
api . LocalLB . Pool . get_object_status ( pool_names = [ pool ] )
result = True
result = True
except bigsuds . OperationFailed , e :
except bigsuds . OperationFailed as e :
if " was not found " in str ( e ) :
if " was not found " in str ( e ) :
result = False
result = False
else :
else :
@ -259,6 +269,7 @@ def pool_exists(api, pool):
raise
raise
return result
return result
def create_pool ( api , pool , lb_method ) :
def create_pool ( api , pool , lb_method ) :
# create requires lb_method but we don't want to default
# create requires lb_method but we don't want to default
# to a value on subsequent runs
# to a value on subsequent runs
@ -268,18 +279,22 @@ def create_pool(api, pool, lb_method):
api . LocalLB . Pool . create_v2 ( pool_names = [ pool ] , lb_methods = [ lb_method ] ,
api . LocalLB . Pool . create_v2 ( pool_names = [ pool ] , lb_methods = [ lb_method ] ,
members = [ [ ] ] )
members = [ [ ] ] )
def remove_pool ( api , pool ) :
def remove_pool ( api , pool ) :
api . LocalLB . Pool . delete_pool ( pool_names = [ pool ] )
api . LocalLB . Pool . delete_pool ( pool_names = [ pool ] )
def get_lb_method ( api , pool ) :
def get_lb_method ( api , pool ) :
lb_method = api . LocalLB . Pool . get_lb_method ( pool_names = [ pool ] ) [ 0 ]
lb_method = api . LocalLB . Pool . get_lb_method ( pool_names = [ pool ] ) [ 0 ]
lb_method = lb_method . strip ( ) . replace ( ' LB_METHOD_ ' , ' ' ) . lower ( )
lb_method = lb_method . strip ( ) . replace ( ' LB_METHOD_ ' , ' ' ) . lower ( )
return lb_method
return lb_method
def set_lb_method ( api , pool , lb_method ) :
def set_lb_method ( api , pool , lb_method ) :
lb_method = " LB_METHOD_ %s " % lb_method . strip ( ) . upper ( )
lb_method = " LB_METHOD_ %s " % lb_method . strip ( ) . upper ( )
api . LocalLB . Pool . set_lb_method ( pool_names = [ pool ] , lb_methods = [ lb_method ] )
api . LocalLB . Pool . set_lb_method ( pool_names = [ pool ] , lb_methods = [ lb_method ] )
def get_monitors ( api , pool ) :
def get_monitors ( api , pool ) :
result = api . LocalLB . Pool . get_monitor_association ( pool_names = [ pool ] ) [ 0 ] [ ' monitor_rule ' ]
result = api . LocalLB . Pool . get_monitor_association ( pool_names = [ pool ] ) [ 0 ] [ ' monitor_rule ' ]
monitor_type = result [ ' type ' ] . split ( " MONITOR_RULE_TYPE_ " ) [ - 1 ] . lower ( )
monitor_type = result [ ' type ' ] . split ( " MONITOR_RULE_TYPE_ " ) [ - 1 ] . lower ( )
@ -287,35 +302,43 @@ def get_monitors(api, pool):
monitor_templates = result [ ' monitor_templates ' ]
monitor_templates = result [ ' monitor_templates ' ]
return ( monitor_type , quorum , monitor_templates )
return ( monitor_type , quorum , monitor_templates )
def set_monitors ( api , pool , monitor_type , quorum , monitor_templates ) :
def set_monitors ( api , pool , monitor_type , quorum , monitor_templates ) :
monitor_type = " MONITOR_RULE_TYPE_ %s " % monitor_type . strip ( ) . upper ( )
monitor_type = " MONITOR_RULE_TYPE_ %s " % monitor_type . strip ( ) . upper ( )
monitor_rule = { ' type ' : monitor_type , ' quorum ' : quorum , ' monitor_templates ' : monitor_templates }
monitor_rule = { ' type ' : monitor_type , ' quorum ' : quorum , ' monitor_templates ' : monitor_templates }
monitor_association = { ' pool_name ' : pool , ' monitor_rule ' : monitor_rule }
monitor_association = { ' pool_name ' : pool , ' monitor_rule ' : monitor_rule }
api . LocalLB . Pool . set_monitor_association ( monitor_associations = [ monitor_association ] )
api . LocalLB . Pool . set_monitor_association ( monitor_associations = [ monitor_association ] )
def get_slow_ramp_time ( api , pool ) :
def get_slow_ramp_time ( api , pool ) :
result = api . LocalLB . Pool . get_slow_ramp_time ( pool_names = [ pool ] ) [ 0 ]
result = api . LocalLB . Pool . get_slow_ramp_time ( pool_names = [ pool ] ) [ 0 ]
return result
return result
def set_slow_ramp_time ( api , pool , seconds ) :
def set_slow_ramp_time ( api , pool , seconds ) :
api . LocalLB . Pool . set_slow_ramp_time ( pool_names = [ pool ] , values = [ seconds ] )
api . LocalLB . Pool . set_slow_ramp_time ( pool_names = [ pool ] , values = [ seconds ] )
def get_reselect_tries ( api , pool ) :
def get_reselect_tries ( api , pool ) :
result = api . LocalLB . Pool . get_reselect_tries ( pool_names = [ pool ] ) [ 0 ]
result = api . LocalLB . Pool . get_reselect_tries ( pool_names = [ pool ] ) [ 0 ]
return result
return result
def set_reselect_tries ( api , pool , tries ) :
def set_reselect_tries ( api , pool , tries ) :
api . LocalLB . Pool . set_reselect_tries ( pool_names = [ pool ] , values = [ tries ] )
api . LocalLB . Pool . set_reselect_tries ( pool_names = [ pool ] , values = [ tries ] )
def get_action_on_service_down ( api , pool ) :
def get_action_on_service_down ( api , pool ) :
result = api . LocalLB . Pool . get_action_on_service_down ( pool_names = [ pool ] ) [ 0 ]
result = api . LocalLB . Pool . get_action_on_service_down ( pool_names = [ pool ] ) [ 0 ]
result = result . split ( " SERVICE_DOWN_ACTION_ " ) [ - 1 ] . lower ( )
result = result . split ( " SERVICE_DOWN_ACTION_ " ) [ - 1 ] . lower ( )
return result
return result
def set_action_on_service_down ( api , pool , action ) :
def set_action_on_service_down ( api , pool , action ) :
action = " SERVICE_DOWN_ACTION_ %s " % action . strip ( ) . upper ( )
action = " SERVICE_DOWN_ACTION_ %s " % action . strip ( ) . upper ( )
api . LocalLB . Pool . set_action_on_service_down ( pool_names = [ pool ] , actions = [ action ] )
api . LocalLB . Pool . set_action_on_service_down ( pool_names = [ pool ] , actions = [ action ] )
def member_exists ( api , pool , address , port ) :
def member_exists ( api , pool , address , port ) :
# hack to determine if member exists
# hack to determine if member exists
result = False
result = False
@ -324,7 +347,7 @@ def member_exists(api, pool, address, port):
api . LocalLB . Pool . get_member_object_status ( pool_names = [ pool ] ,
api . LocalLB . Pool . get_member_object_status ( pool_names = [ pool ] ,
members = [ members ] )
members = [ members ] )
result = True
result = True
except bigsuds . OperationFailed , e :
except bigsuds . OperationFailed as e :
if " was not found " in str ( e ) :
if " was not found " in str ( e ) :
result = False
result = False
else :
else :
@ -332,12 +355,13 @@ def member_exists(api, pool, address, port):
raise
raise
return result
return result
def delete_node_address ( api , address ) :
def delete_node_address ( api , address ) :
result = False
result = False
try :
try :
api . LocalLB . NodeAddressV2 . delete_node_address ( nodes = [ address ] )
api . LocalLB . NodeAddressV2 . delete_node_address ( nodes = [ address ] )
result = True
result = True
except bigsuds . OperationFailed , e :
except bigsuds . OperationFailed as e :
if " is referenced by a member of pool " in str ( e ) :
if " is referenced by a member of pool " in str ( e ) :
result = False
result = False
else :
else :
@ -345,14 +369,17 @@ def delete_node_address(api, address):
raise
raise
return result
return result
def remove_pool_member ( api , pool , address , port ) :
def remove_pool_member ( api , pool , address , port ) :
members = [ { ' address ' : address , ' port ' : port } ]
members = [ { ' address ' : address , ' port ' : port } ]
api . LocalLB . Pool . remove_member_v2 ( pool_names = [ pool ] , members = [ members ] )
api . LocalLB . Pool . remove_member_v2 ( pool_names = [ pool ] , members = [ members ] )
def add_pool_member ( api , pool , address , port ) :
def add_pool_member ( api , pool , address , port ) :
members = [ { ' address ' : address , ' port ' : port } ]
members = [ { ' address ' : address , ' port ' : port } ]
api . LocalLB . Pool . add_member_v2 ( pool_names = [ pool ] , members = [ members ] )
api . LocalLB . Pool . add_member_v2 ( pool_names = [ pool ] , members = [ members ] )
def main ( ) :
def main ( ) :
lb_method_choices = [ ' round_robin ' , ' ratio_member ' ,
lb_method_choices = [ ' round_robin ' , ' ratio_member ' ,
' least_connection_member ' , ' observed_member ' ,
' least_connection_member ' , ' observed_member ' ,
@ -371,8 +398,9 @@ def main():
service_down_choices = [ ' none ' , ' reset ' , ' drop ' , ' reselect ' ]
service_down_choices = [ ' none ' , ' reset ' , ' drop ' , ' reselect ' ]
argument_spec = f5_argument_spec ( ) ;
argument_spec = f5_argument_spec ( )
argument_spec . update ( dict (
meta_args = dict (
name = dict ( type = ' str ' , required = True , aliases = [ ' pool ' ] ) ,
name = dict ( type = ' str ' , required = True , aliases = [ ' pool ' ] ) ,
lb_method = dict ( type = ' str ' , choices = lb_method_choices ) ,
lb_method = dict ( type = ' str ' , choices = lb_method_choices ) ,
monitor_type = dict ( type = ' str ' , choices = monitor_type_choices ) ,
monitor_type = dict ( type = ' str ' , choices = monitor_type_choices ) ,
@ -384,7 +412,7 @@ def main():
host = dict ( type = ' str ' , aliases = [ ' address ' ] ) ,
host = dict ( type = ' str ' , aliases = [ ' address ' ] ) ,
port = dict ( type = ' int ' )
port = dict ( type = ' int ' )
)
)
)
argument_spec . update ( meta_args )
module = AnsibleModule (
module = AnsibleModule (
argument_spec = argument_spec ,
argument_spec = argument_spec ,
@ -479,7 +507,7 @@ def main():
try :
try :
remove_pool ( api , pool )
remove_pool ( api , pool )
result = { ' changed ' : True }
result = { ' changed ' : True }
except bigsuds . OperationFailed , e :
except bigsuds . OperationFailed as e :
if " was not found " in str ( e ) :
if " was not found " in str ( e ) :
result = { ' changed ' : False }
result = { ' changed ' : False }
else :
else :
@ -502,7 +530,7 @@ def main():
try :
try :
create_pool ( api , pool , lb_method )
create_pool ( api , pool , lb_method )
result = { ' changed ' : True }
result = { ' changed ' : True }
except bigsuds . OperationFailed , e :
except bigsuds . OperationFailed as e :
if " already exists " in str ( e ) :
if " already exists " in str ( e ) :
update = True
update = True
else :
else :
@ -558,12 +586,11 @@ def main():
add_pool_member ( api , pool , address , port )
add_pool_member ( api , pool , address , port )
result = { ' changed ' : True }
result = { ' changed ' : True }
except Exception , e :
except Exception as e :
module . fail_json ( msg = " received exception: %s " % e )
module . fail_json ( msg = " received exception: %s " % e )
module . exit_json ( * * result )
module . exit_json ( * * result )
# import module snippets
from ansible . module_utils . basic import *
from ansible . module_utils . basic import *
from ansible . module_utils . f5 import *
from ansible . module_utils . f5 import *