Adds a series of new parameters to bigip_virtual_server (#48777)

This commit is contained in:
Tim Rupp 2018-11-15 20:33:37 -08:00 committed by GitHub
commit f8f2746efc
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23

View file

@ -279,6 +279,34 @@ options:
- When creating a new virtual server, the default is C(enabled). - When creating a new virtual server, the default is C(enabled).
type: bool type: bool
version_added: 2.6 version_added: 2.6
source_port:
description:
- Specifies whether the system preserves the source port of the connection.
- When creating a new virtual server, if this parameter is not specified, the default is C(preserve).
choices:
- preserve
- preserve-strict
- change
version_added: 2.8
mirror:
description:
- Specifies that the system mirrors connections on each member of a redundant pair.
- When creating a new virtual server, if this parameter is not specified, the default is C(disabled).
type: bool
version_added: 2.8
mask:
description:
- Specifies the destination address network mask. This parameter will work with IPv4 and IPv6 tye of addresses.
- This is an optional parameter which can be specified when creating or updating virtual server.
- If C(destination) is provided in CIDR notation format and C(mask) is provided the mask parameter takes
precedence.
- If catchall destination is specified, i.e. C(0.0.0.0) for IPv4 C(::) for IPv6,
mask parameter is set to C(any) or C(any6) respectively)
- When the C(destination) is provided not in CIDR notation and C(mask) is not specified, C(255.255.255.255) or
C(ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff) is set for IPv4 and IPv6 addresses respectively.
- When C(destination) is provided in CIDR notation format and C(mask) is not specified the mask parameter is
inferred from C(destination).
version_added: 2.8
ip_protocol: ip_protocol:
description: description:
- Specifies a network protocol name you want the system to use to direct traffic - Specifies a network protocol name you want the system to use to direct traffic
@ -364,6 +392,7 @@ options:
extends_documentation_fragment: f5 extends_documentation_fragment: f5
author: author:
- Tim Rupp (@caphrim007) - Tim Rupp (@caphrim007)
- Wojciech Wypior (@wojtek0806)
''' '''
EXAMPLES = r''' EXAMPLES = r'''
@ -608,6 +637,16 @@ port_translation:
returned: changed returned: changed
type: bool type: bool
sample: True sample: True
source_port:
description: Specifies whether the system preserves the source port of the connection.
returned: changed
type: string
sample: change
mirror:
description: Specifies that the system mirrors connections on each member of a redundant pair.
returned: changed
type: bool
sample: True
ip_protocol: ip_protocol:
description: The new value of the IP protocol. description: The new value of the IP protocol.
returned: changed returned: changed
@ -629,7 +668,6 @@ security_log_profiles:
type: list type: list
sample: ['/Common/profile1', '/Common/profile2'] sample: ['/Common/profile1', '/Common/profile2']
''' '''
import os import os
import re import re
@ -652,10 +690,13 @@ try:
from library.module_utils.network.f5.common import transform_name from library.module_utils.network.f5.common import transform_name
from library.module_utils.network.f5.common import mark_managed_by from library.module_utils.network.f5.common import mark_managed_by
from library.module_utils.network.f5.common import only_has_managed_metadata from library.module_utils.network.f5.common import only_has_managed_metadata
from library.module_utils.network.f5.common import flatten_boolean
from library.module_utils.network.f5.compare import cmp_simple_list from library.module_utils.network.f5.compare import cmp_simple_list
from library.module_utils.network.f5.ipaddress import is_valid_ip from library.module_utils.network.f5.ipaddress import is_valid_ip
from library.module_utils.network.f5.ipaddress import ip_interface from library.module_utils.network.f5.ipaddress import ip_interface
from library.module_utils.network.f5.ipaddress import validate_ip_v6_address from library.module_utils.network.f5.ipaddress import validate_ip_v6_address
from library.module_utils.network.f5.ipaddress import get_netmask
from library.module_utils.network.f5.ipaddress import compress_address
except ImportError: except ImportError:
from ansible.module_utils.network.f5.bigip import F5RestClient from ansible.module_utils.network.f5.bigip import F5RestClient
from ansible.module_utils.network.f5.common import MANAGED_BY_ANNOTATION_VERSION from ansible.module_utils.network.f5.common import MANAGED_BY_ANNOTATION_VERSION
@ -670,10 +711,13 @@ except ImportError:
from ansible.module_utils.network.f5.common import transform_name from ansible.module_utils.network.f5.common import transform_name
from ansible.module_utils.network.f5.common import mark_managed_by from ansible.module_utils.network.f5.common import mark_managed_by
from ansible.module_utils.network.f5.common import only_has_managed_metadata from ansible.module_utils.network.f5.common import only_has_managed_metadata
from ansible.module_utils.network.f5.common import flatten_boolean
from ansible.module_utils.network.f5.compare import cmp_simple_list from ansible.module_utils.network.f5.compare import cmp_simple_list
from ansible.module_utils.network.f5.ipaddress import is_valid_ip from ansible.module_utils.network.f5.ipaddress import is_valid_ip
from ansible.module_utils.network.f5.ipaddress import ip_interface from ansible.module_utils.network.f5.ipaddress import ip_interface
from ansible.module_utils.network.f5.ipaddress import validate_ip_v6_address from ansible.module_utils.network.f5.ipaddress import validate_ip_v6_address
from ansible.module_utils.network.f5.ipaddress import get_netmask
from ansible.module_utils.network.f5.ipaddress import compress_address
class Parameters(AnsibleF5Parameters): class Parameters(AnsibleF5Parameters):
@ -693,6 +737,7 @@ class Parameters(AnsibleF5Parameters):
'fwStagedPolicy': 'firewall_staged_policy', 'fwStagedPolicy': 'firewall_staged_policy',
'securityLogProfiles': 'security_log_profiles', 'securityLogProfiles': 'security_log_profiles',
'securityNatPolicy': 'security_nat_policy', 'securityNatPolicy': 'security_nat_policy',
'sourcePort': 'source_port',
} }
api_attributes = [ api_attributes = [
@ -725,6 +770,9 @@ class Parameters(AnsibleF5Parameters):
'fwStagedPolicy', 'fwStagedPolicy',
'securityLogProfiles', 'securityLogProfiles',
'securityNatPolicy', 'securityNatPolicy',
'sourcePort',
'mirror',
'mask',
] ]
updatables = [ updatables = [
@ -751,6 +799,9 @@ class Parameters(AnsibleF5Parameters):
'firewall_staged_policy', 'firewall_staged_policy',
'security_log_profiles', 'security_log_profiles',
'security_nat_policy', 'security_nat_policy',
'source_port',
'mirror',
'mask',
] ]
returnables = [ returnables = [
@ -781,6 +832,9 @@ class Parameters(AnsibleF5Parameters):
'firewall_staged_policy', 'firewall_staged_policy',
'security_log_profiles', 'security_log_profiles',
'security_nat_policy', 'security_nat_policy',
'source_port',
'mirror',
'mask',
] ]
profiles_mutex = [ profiles_mutex = [
@ -1072,11 +1126,11 @@ class ApiParameters(Parameters):
@property @property
def destination_tuple(self): def destination_tuple(self):
Destination = namedtuple('Destination', ['ip', 'port', 'route_domain']) Destination = namedtuple('Destination', ['ip', 'port', 'route_domain', 'mask'])
# Remove the partition # Remove the partition
if self._values['destination'] is None: if self._values['destination'] is None:
result = Destination(ip=None, port=None, route_domain=None) result = Destination(ip=None, port=None, route_domain=None, mask=None)
return result return result
destination = re.sub(r'^/[a-zA-Z0-9_.-]+/', '', self._values['destination']) destination = re.sub(r'^/[a-zA-Z0-9_.-]+/', '', self._values['destination'])
@ -1084,7 +1138,8 @@ class ApiParameters(Parameters):
result = Destination( result = Destination(
ip=destination, ip=destination,
port=None, port=None,
route_domain=None route_domain=None,
mask=self.mask
) )
return result return result
@ -1114,7 +1169,8 @@ class ApiParameters(Parameters):
result = Destination( result = Destination(
ip=matches.group('ip'), ip=matches.group('ip'),
port=port, port=port,
route_domain=int(matches.group('route_domain')) route_domain=int(matches.group('route_domain')),
mask=self.mask
) )
return result return result
@ -1129,7 +1185,8 @@ class ApiParameters(Parameters):
result = Destination( result = Destination(
ip=matches.group('ip'), ip=matches.group('ip'),
port=None, port=None,
route_domain=int(matches.group('route_domain')) route_domain=int(matches.group('route_domain')),
mask=self.mask
) )
return result return result
@ -1144,7 +1201,8 @@ class ApiParameters(Parameters):
result = Destination( result = Destination(
ip=ip, ip=ip,
port=int(port), port=int(port),
route_domain=None route_domain=None,
mask=self.mask
) )
return result return result
elif len(parts) == 2: elif len(parts) == 2:
@ -1163,11 +1221,12 @@ class ApiParameters(Parameters):
result = Destination( result = Destination(
ip=ip, ip=ip,
port=port, port=port,
route_domain=None route_domain=None,
mask=self.mask
) )
return result return result
else: else:
result = Destination(ip=None, port=None, route_domain=None) result = Destination(ip=None, port=None, route_domain=None, mask=None)
return result return result
@property @property
@ -1381,7 +1440,7 @@ class ModuleParameters(Parameters):
@property @property
def destination(self): def destination(self):
addr = self._values['destination'].split("%")[0] addr = self._values['destination'].split("%")[0].split('/')[0]
if not is_valid_ip(addr): if not is_valid_ip(addr):
raise F5ModuleError( raise F5ModuleError(
"The provided destination is not a valid IP address" "The provided destination is not a valid IP address"
@ -1390,15 +1449,38 @@ class ModuleParameters(Parameters):
return result return result
@property @property
def destination_tuple(self): def route_domain(self):
Destination = namedtuple('Destination', ['ip', 'port', 'route_domain'])
if self._values['destination'] is None: if self._values['destination'] is None:
result = Destination(ip=None, port=None, route_domain=None) return None
result = self._values['destination'].split("%")
if len(result) > 1:
return int(result[1])
return None
@property
def destination_tuple(self):
Destination = namedtuple('Destination', ['ip', 'port', 'route_domain', 'mask'])
if self._values['destination'] is None:
result = Destination(ip=None, port=None, route_domain=None, mask=None)
return result return result
addr = self._values['destination'].split("%")[0] sanitized = self._values['destination'].split("%")[0].split('/')[0]
result = Destination(ip=addr, port=self.port, route_domain=self.route_domain) addr = compress_address(u'{0}'.format(sanitized))
result = Destination(ip=addr, port=self.port, route_domain=self.route_domain, mask=self.mask)
return result return result
@property
def mask(self):
if self._values['destination'] is None:
return None
addr = self._values['destination'].split("%")[0]
if addr in ['0.0.0.0', '0.0.0.0/any', '0.0.0.0/0']:
return 'any'
if addr in ['::', '::/0', '::/any6']:
return 'any6'
if self._values['mask'] is None:
return get_netmask(u'{0}'.format(addr))
return compress_address(u'{0}'.format(self._values['mask']))
@property @property
def port(self): def port(self):
if self._values['port'] is None: if self._values['port'] is None:
@ -1705,6 +1787,15 @@ class ModuleParameters(Parameters):
return result return result
return None return None
@property
def mirror(self):
result = flatten_boolean(self._values['mirror'])
if result is None:
return None
if result == 'yes':
return 'enabled'
return 'disabled'
class Changes(Parameters): class Changes(Parameters):
pass pass
@ -1828,6 +1919,14 @@ class UsableChanges(Changes):
class ReportableChanges(Changes): class ReportableChanges(Changes):
@property
def mirror(self):
if self._values['mirror'] is None:
return None
elif self._values['mirror'] == 'enabled':
return 'yes'
return 'no'
@property @property
def snat(self): def snat(self):
if self._values['snat'] is None: if self._values['snat'] is None:
@ -2860,7 +2959,7 @@ class ModuleManager(object):
return True return True
return False return False
def exists(self): # lgtm [py/similar-function] def exists(self):
uri = "https://{0}:{1}/mgmt/tm/ltm/virtual/{2}".format( uri = "https://{0}:{1}/mgmt/tm/ltm/virtual/{2}".format(
self.client.provider['server'], self.client.provider['server'],
self.client.provider['server_port'], self.client.provider['server_port'],
@ -3017,6 +3116,11 @@ class ArgumentSpec(object):
), ),
address_translation=dict(type='bool'), address_translation=dict(type='bool'),
port_translation=dict(type='bool'), port_translation=dict(type='bool'),
source_port=dict(
choices=[
'preserve', 'preserve-strict', 'change'
]
),
ip_protocol=dict( ip_protocol=dict(
choices=[ choices=[
'ah', 'any', 'bna', 'esp', 'etherip', 'gre', 'icmp', 'ipencap', 'ipv6', 'ah', 'any', 'bna', 'esp', 'etherip', 'gre', 'icmp', 'ipencap', 'ipv6',
@ -3031,6 +3135,8 @@ class ArgumentSpec(object):
'performance-http', 'performance-l4', 'reject', 'stateless', 'dhcp' 'performance-http', 'performance-l4', 'reject', 'stateless', 'dhcp'
] ]
), ),
mirror=dict(type='bool'),
mask=dict(),
firewall_staged_policy=dict(), firewall_staged_policy=dict(),
firewall_enforced_policy=dict(), firewall_enforced_policy=dict(),
security_log_profiles=dict(type='list'), security_log_profiles=dict(type='list'),
@ -3060,8 +3166,9 @@ def main():
mutually_exclusive=spec.mutually_exclusive mutually_exclusive=spec.mutually_exclusive
) )
client = F5RestClient(**module.params)
try: try:
client = F5RestClient(**module.params)
mm = ModuleManager(module=module, client=client) mm = ModuleManager(module=module, client=client)
results = mm.exec_module() results = mm.exec_module()
exit_json(module, results, client) exit_json(module, results, client)