Adds style conventions to bigip_pool_member (#2535)

A number of coding conventions have been adopted for new F5 modules
that are in development. To ensure common usage across the modules,
this module needed to be updated to reflect those conventions.

No functional code changes were made.
This commit is contained in:
Tim Rupp 2016-07-07 22:56:09 -07:00 committed by René Moser
parent d5ebe033e3
commit 188a01ff1a

View file

@ -1,6 +1,6 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
#
# (c) 2013, Matt Hite <mhite@hotmail.com>
#
# This file is part of Ansible
@ -21,204 +21,212 @@
DOCUMENTATION = '''
---
module: bigip_pool_member
short_description: "Manages F5 BIG-IP LTM pool members"
short_description: Manages F5 BIG-IP LTM pool members
description:
- "Manages F5 BIG-IP LTM pool members via iControl SOAP API"
version_added: "1.4"
- Manages F5 BIG-IP LTM pool members via iControl SOAP API
version_added: 1.4
author:
- Matt Hite (@mhite)
- Tim Rupp (@caphrim007)
- Matt Hite (@mhite)
- Tim Rupp (@caphrim007)
notes:
- "Requires BIG-IP software version >= 11"
- "F5 developed module 'bigsuds' required (see http://devcentral.f5.com)"
- "Best run as a local_action in your playbook"
- "Supersedes bigip_pool for managing pool members"
- Requires BIG-IP software version >= 11
- F5 developed module 'bigsuds' required (see http://devcentral.f5.com)
- Best run as a local_action in your playbook
- Supersedes bigip_pool for managing pool members
requirements:
- bigsuds
- bigsuds
options:
server:
description:
- BIG-IP host
required: true
server_port:
description:
- BIG-IP server port
required: false
default: 443
version_added: "2.2"
user:
description:
- BIG-IP username
required: true
password:
description:
- BIG-IP password
required: true
validate_certs:
description:
- If C(no), SSL certificates will not be validated. This should only be used
on personally controlled sites. Prior to 2.0, this module would always
validate on python >= 2.7.9 and never validate on python <= 2.7.8
required: false
default: 'yes'
choices: ['yes', 'no']
version_added: 2.0
state:
description:
- Pool member state
required: true
default: present
choices: ['present', 'absent']
session_state:
description:
- Set new session availability status for pool member
version_added: "2.0"
required: false
default: null
choices: ['enabled', 'disabled']
monitor_state:
description:
- Set monitor availability status for pool member
version_added: "2.0"
required: false
default: null
choices: ['enabled', 'disabled']
pool:
description:
- Pool name. This pool must exist.
required: true
partition:
description:
- Partition
required: false
default: 'Common'
host:
description:
- Pool member IP
required: true
aliases: ['address', 'name']
port:
description:
- Pool member port
required: true
connection_limit:
description:
- Pool member connection limit. Setting this to 0 disables the limit.
required: false
default: null
server:
description:
description:
- Pool member description
required: false
default: null
rate_limit:
description:
- Pool member rate limit (connections-per-second). Setting this to 0 disables the limit.
required: false
default: null
ratio:
description:
- Pool member ratio weight. Valid values range from 1 through 100. New pool members -- unless overriden with this value -- default to 1.
required: false
default: null
preserve_node:
description:
- When state is absent and the pool member is no longer referenced in other pools, the default behavior removes the unused node object. Setting this to 'yes' disables this behavior.
required: false
default: 'no'
choices: ['yes', 'no']
version_added: 2.1
- BIG-IP host
required: true
server_port:
description:
- BIG-IP server port
required: false
default: 443
version_added: "2.2"
user:
description:
- BIG-IP username
required: true
password:
description:
- BIG-IP password
required: true
validate_certs:
description:
- If C(no), SSL certificates will not be validated. This should only be used
on personally controlled sites. Prior to 2.0, this module would always
validate on python >= 2.7.9 and never validate on python <= 2.7.8
required: false
default: 'yes'
choices:
- yes
- no
version_added: 2.0
state:
description:
- Pool member state
required: true
default: present
choices:
- present
- absent
session_state:
description:
- Set new session availability status for pool member
version_added: 2.0
required: false
default: null
choices:
- enabled
- disabled
monitor_state:
description:
- Set monitor availability status for pool member
version_added: 2.0
required: false
default: null
choices:
- enabled
- disabled
pool:
description:
- Pool name. This pool must exist.
required: true
partition:
description:
- Partition
required: false
default: 'Common'
host:
description:
- Pool member IP
required: true
aliases:
- address
- name
port:
description:
- Pool member port
required: true
connection_limit:
description:
- Pool member connection limit. Setting this to 0 disables the limit.
required: false
default: null
description:
description:
- Pool member description
required: false
default: null
rate_limit:
description:
- Pool member rate limit (connections-per-second). Setting this to 0
disables the limit.
required: false
default: null
ratio:
description:
- Pool member ratio weight. Valid values range from 1 through 100.
New pool members -- unless overriden with this value -- default
to 1.
required: false
default: null
preserve_node:
description:
- When state is absent and the pool member is no longer referenced
in other pools, the default behavior removes the unused node
o bject. Setting this to 'yes' disables this behavior.
required: false
default: 'no'
choices:
- yes
- no
version_added: 2.1
'''
EXAMPLES = '''
- name: Add pool member
bigip_pool_member:
server: "lb.mydomain.com"
user: "admin"
password: "secret"
state: "present"
pool: "my-pool"
partition: "Common"
host: "{{ ansible_default_ipv4["address"] }}"
port: 80
description: "web server"
connection_limit: 100
rate_limit: 50
ratio: 2
delegate_to: localhost
## playbook task examples:
- name: Modify pool member ratio and description
bigip_pool_member:
server: "lb.mydomain.com"
user: "admin"
password: "secret"
state: "present"
pool: "my-pool"
partition: "Common"
host: "{{ ansible_default_ipv4["address"] }}"
port: 80
ratio: 1
description: "nginx server"
delegate_to: localhost
---
# file bigip-test.yml
# ...
- hosts: bigip-test
tasks:
- name: Add pool member
local_action: >
bigip_pool_member
server=lb.mydomain.com
user=admin
password=mysecret
state=present
pool=matthite-pool
partition=matthite
host="{{ ansible_default_ipv4["address"] }}"
port=80
description="web server"
connection_limit=100
rate_limit=50
ratio=2
- name: Modify pool member ratio and description
local_action: >
bigip_pool_member
server=lb.mydomain.com
user=admin
password=mysecret
state=present
pool=matthite-pool
partition=matthite
host="{{ ansible_default_ipv4["address"] }}"
port=80
ratio=1
description="nginx server"
- name: Remove pool member from pool
local_action: >
bigip_pool_member
server=lb.mydomain.com
user=admin
password=mysecret
state=absent
pool=matthite-pool
partition=matthite
host="{{ ansible_default_ipv4["address"] }}"
port=80
- name: Remove pool member from pool
bigip_pool_member:
server: "lb.mydomain.com"
user: "admin"
password: "secret"
state: "absent"
pool: "my-pool"
partition: "Common"
host: "{{ ansible_default_ipv4["address"] }}"
port: 80
delegate_to: localhost
# The BIG-IP GUI doesn't map directly to the API calls for "Pool ->
# Members -> State". The following states map to API monitor
# and session states.
#
# Enabled (all traffic allowed):
# monitor_state=enabled, session_state=enabled
# Disabled (only persistent or active connections allowed):
# monitor_state=enabled, session_state=disabled
# Forced offline (only active connections allowed):
# monitor_state=disabled, session_state=disabled
#
# See https://devcentral.f5.com/questions/icontrol-equivalent-call-for-b-node-down
- name: Force pool member offline
local_action: >
bigip_pool_member
server=lb.mydomain.com
user=admin
password=mysecret
state=present
session_state=disabled
monitor_state=disabled
pool=matthite-pool
partition=matthite
host="{{ ansible_default_ipv4["address"] }}"
port=80
# The BIG-IP GUI doesn't map directly to the API calls for "Pool ->
# Members -> State". The following states map to API monitor
# and session states.
#
# Enabled (all traffic allowed):
# monitor_state=enabled, session_state=enabled
# Disabled (only persistent or active connections allowed):
# monitor_state=enabled, session_state=disabled
# Forced offline (only active connections allowed):
# monitor_state=disabled, session_state=disabled
#
# See https://devcentral.f5.com/questions/icontrol-equivalent-call-for-b-node-down
- name: Force pool member offline
bigip_pool_member:
server: "lb.mydomain.com"
user: "admin"
password: "secret"
state: "present"
session_state: "disabled"
monitor_state: "disabled"
pool: "my-pool"
partition: "Common"
host: "{{ ansible_default_ipv4["address"] }}"
port: 80
delegate_to: localhost
'''
def pool_exists(api, pool):
# hack to determine if pool exists
result = False
try:
api.LocalLB.Pool.get_object_status(pool_names=[pool])
result = True
except bigsuds.OperationFailed, e:
except bigsuds.OperationFailed as e:
if "was not found" in str(e):
result = False
else:
@ -226,6 +234,7 @@ def pool_exists(api, pool):
raise
return result
def member_exists(api, pool, address, port):
# hack to determine if member exists
result = False
@ -234,7 +243,7 @@ def member_exists(api, pool, address, port):
api.LocalLB.Pool.get_member_object_status(pool_names=[pool],
members=[members])
result = True
except bigsuds.OperationFailed, e:
except bigsuds.OperationFailed as e:
if "was not found" in str(e):
result = False
else:
@ -242,12 +251,13 @@ def member_exists(api, pool, address, port):
raise
return result
def delete_node_address(api, address):
result = False
try:
api.LocalLB.NodeAddressV2.delete_node_address(nodes=[address])
result = True
except bigsuds.OperationFailed, e:
except bigsuds.OperationFailed as e:
if "is referenced by a member of pool" in str(e):
result = False
else:
@ -255,96 +265,157 @@ def delete_node_address(api, address):
raise
return result
def remove_pool_member(api, pool, address, 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):
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 get_connection_limit(api, pool, address, port):
members = [{'address': address, 'port': port}]
result = api.LocalLB.Pool.get_member_connection_limit(pool_names=[pool], members=[members])[0][0]
result = api.LocalLB.Pool.get_member_connection_limit(
pool_names=[pool],
members=[members]
)[0][0]
return result
def set_connection_limit(api, pool, address, port, limit):
members = [{'address': address, 'port': port}]
api.LocalLB.Pool.set_member_connection_limit(pool_names=[pool], members=[members], limits=[[limit]])
api.LocalLB.Pool.set_member_connection_limit(
pool_names=[pool],
members=[members],
limits=[[limit]]
)
def get_description(api, pool, address, port):
members = [{'address': address, 'port': port}]
result = api.LocalLB.Pool.get_member_description(pool_names=[pool], members=[members])[0][0]
result = api.LocalLB.Pool.get_member_description(
pool_names=[pool],
members=[members]
)[0][0]
return result
def set_description(api, pool, address, port, description):
members = [{'address': address, 'port': port}]
api.LocalLB.Pool.set_member_description(pool_names=[pool], members=[members], descriptions=[[description]])
api.LocalLB.Pool.set_member_description(
pool_names=[pool],
members=[members],
descriptions=[[description]]
)
def get_rate_limit(api, pool, address, port):
members = [{'address': address, 'port': port}]
result = api.LocalLB.Pool.get_member_rate_limit(pool_names=[pool], members=[members])[0][0]
result = api.LocalLB.Pool.get_member_rate_limit(
pool_names=[pool],
members=[members]
)[0][0]
return result
def set_rate_limit(api, pool, address, port, limit):
members = [{'address': address, 'port': port}]
api.LocalLB.Pool.set_member_rate_limit(pool_names=[pool], members=[members], limits=[[limit]])
api.LocalLB.Pool.set_member_rate_limit(
pool_names=[pool],
members=[members],
limits=[[limit]]
)
def get_ratio(api, pool, address, port):
members = [{'address': address, 'port': port}]
result = api.LocalLB.Pool.get_member_ratio(pool_names=[pool], members=[members])[0][0]
result = api.LocalLB.Pool.get_member_ratio(
pool_names=[pool],
members=[members]
)[0][0]
return result
def set_ratio(api, pool, address, port, ratio):
members = [{'address': address, 'port': port}]
api.LocalLB.Pool.set_member_ratio(pool_names=[pool], members=[members], ratios=[[ratio]])
api.LocalLB.Pool.set_member_ratio(
pool_names=[pool],
members=[members],
ratios=[[ratio]]
)
def set_member_session_enabled_state(api, pool, address, port, session_state):
members = [{'address': address, 'port': port}]
session_state = ["STATE_%s" % session_state.strip().upper()]
api.LocalLB.Pool.set_member_session_enabled_state(pool_names=[pool], members=[members], session_states=[session_state])
api.LocalLB.Pool.set_member_session_enabled_state(
pool_names=[pool],
members=[members],
session_states=[session_state]
)
def get_member_session_status(api, pool, address, port):
members = [{'address': address, 'port': port}]
result = api.LocalLB.Pool.get_member_session_status(pool_names=[pool], members=[members])[0][0]
result = api.LocalLB.Pool.get_member_session_status(
pool_names=[pool],
members=[members]
)[0][0]
result = result.split("SESSION_STATUS_")[-1].lower()
return result
def set_member_monitor_state(api, pool, address, port, monitor_state):
members = [{'address': address, 'port': port}]
monitor_state = ["STATE_%s" % monitor_state.strip().upper()]
api.LocalLB.Pool.set_member_monitor_state(pool_names=[pool], members=[members], monitor_states=[monitor_state])
api.LocalLB.Pool.set_member_monitor_state(
pool_names=[pool],
members=[members],
monitor_states=[monitor_state]
)
def get_member_monitor_status(api, pool, address, port):
members = [{'address': address, 'port': port}]
result = api.LocalLB.Pool.get_member_monitor_status(pool_names=[pool], members=[members])[0][0]
result = api.LocalLB.Pool.get_member_monitor_status(
pool_names=[pool],
members=[members]
)[0][0]
result = result.split("MONITOR_STATUS_")[-1].lower()
return result
def main():
argument_spec = f5_argument_spec()
argument_spec.update(dict(
session_state = dict(type='str', choices=['enabled', 'disabled']),
monitor_state = dict(type='str', choices=['enabled', 'disabled']),
pool = dict(type='str', required=True),
host = dict(type='str', required=True, aliases=['address', 'name']),
port = dict(type='int', required=True),
connection_limit = dict(type='int'),
description = dict(type='str'),
rate_limit = dict(type='int'),
ratio = dict(type='int'),
preserve_node = dict(type='bool', default=False)
)
meta_args = dict(
session_state=dict(type='str', choices=['enabled', 'disabled']),
monitor_state=dict(type='str', choices=['enabled', 'disabled']),
pool=dict(type='str', required=True),
host=dict(type='str', required=True, aliases=['address', 'name']),
port=dict(type='int', required=True),
connection_limit=dict(type='int'),
description=dict(type='str'),
rate_limit=dict(type='int'),
ratio=dict(type='int'),
preserve_node=dict(type='bool', default=False)
)
argument_spec.update(meta_args)
module = AnsibleModule(
argument_spec = argument_spec,
argument_spec=argument_spec,
supports_check_mode=True
)
if not bigsuds_found:
module.fail_json(msg="the python bigsuds module is required")
if module.params['validate_certs']:
import ssl
if not hasattr(ssl, 'SSLContext'):
@ -370,9 +441,6 @@ def main():
port = module.params['port']
preserve_node = module.params['preserve_node']
# sanity check user supplied values
if (host and port is None) or (port is not None and not host):
module.fail_json(msg="both host and port must be supplied")
@ -453,12 +521,11 @@ def main():
set_member_monitor_state(api, pool, address, port, monitor_state)
result = {'changed': True}
except Exception, e:
except Exception as e:
module.fail_json(msg="received exception: %s" % e)
module.exit_json(**result)
# import module snippets
from ansible.module_utils.basic import *
from ansible.module_utils.f5 import *