Adds the ip_intelligence_policy parameter to vs module (#48903)

This commit is contained in:
Tim Rupp 2018-11-19 15:24:44 -08:00 committed by GitHub
parent 7546ebf08e
commit 8e6c3b06b8
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 76 additions and 15 deletions

View file

@ -298,10 +298,9 @@ options:
description: description:
- Specifies the destination address network mask. This parameter will work with IPv4 and IPv6 tye of addresses. - 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. - 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 - If C(destination) is set in CIDR notation format and C(mask) is provided the C(mask) parameter takes precedence.
precedence.
- If catchall destination is specified, i.e. C(0.0.0.0) for IPv4 C(::) for IPv6, - 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) 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 - 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. 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 - When C(destination) is provided in CIDR notation format and C(mask) is not specified the mask parameter is
@ -389,6 +388,12 @@ options:
- When specified, the route domain policy overrides the device policy, and - When specified, the route domain policy overrides the device policy, and
is overridden by a virtual server policy. is overridden by a virtual server policy.
type: bool type: bool
ip_intelligence_policy:
description:
- Specifies the IP intelligence policy applied to the virtual server.
- This parameter requires that a valid BIG-IP security module such as ASM or AFM
be provisioned.
version_added: 2.8
extends_documentation_fragment: f5 extends_documentation_fragment: f5
author: author:
- Tim Rupp (@caphrim007) - Tim Rupp (@caphrim007)
@ -667,6 +672,11 @@ security_log_profiles:
returned: changed returned: changed
type: list type: list
sample: ['/Common/profile1', '/Common/profile2'] sample: ['/Common/profile1', '/Common/profile2']
ip_intelligence_policy:
description: The new IP Intelligence Policy assigned to the virtual.
returned: changed
type: string
sample: /Common/ip-intelligence
''' '''
import os import os
import re import re
@ -697,6 +707,7 @@ try:
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 get_netmask
from library.module_utils.network.f5.ipaddress import compress_address from library.module_utils.network.f5.ipaddress import compress_address
from library.module_utils.network.f5.icontrol import modules_provisioned
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
@ -718,6 +729,7 @@ except ImportError:
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 get_netmask
from ansible.module_utils.network.f5.ipaddress import compress_address from ansible.module_utils.network.f5.ipaddress import compress_address
from ansible.module_utils.network.f5.icontrol import modules_provisioned
class Parameters(AnsibleF5Parameters): class Parameters(AnsibleF5Parameters):
@ -738,6 +750,7 @@ class Parameters(AnsibleF5Parameters):
'securityLogProfiles': 'security_log_profiles', 'securityLogProfiles': 'security_log_profiles',
'securityNatPolicy': 'security_nat_policy', 'securityNatPolicy': 'security_nat_policy',
'sourcePort': 'source_port', 'sourcePort': 'source_port',
'ipIntelligencePolicy': 'ip_intelligence_policy',
} }
api_attributes = [ api_attributes = [
@ -773,6 +786,7 @@ class Parameters(AnsibleF5Parameters):
'sourcePort', 'sourcePort',
'mirror', 'mirror',
'mask', 'mask',
'ipIntelligencePolicy',
] ]
updatables = [ updatables = [
@ -802,6 +816,7 @@ class Parameters(AnsibleF5Parameters):
'source_port', 'source_port',
'mirror', 'mirror',
'mask', 'mask',
'ip_intelligence_policy',
] ]
returnables = [ returnables = [
@ -835,6 +850,7 @@ class Parameters(AnsibleF5Parameters):
'source_port', 'source_port',
'mirror', 'mirror',
'mask', 'mask',
'ip_intelligence_policy',
] ]
profiles_mutex = [ profiles_mutex = [
@ -1738,6 +1754,14 @@ class ModuleParameters(Parameters):
return None return None
return fq_name(self.partition, self._values['firewall_staged_policy']) return fq_name(self.partition, self._values['firewall_staged_policy'])
@property
def ip_intelligence_policy(self):
if self._values['ip_intelligence_policy'] is None:
return None
if self._values['ip_intelligence_policy'] in ['', 'none']:
return ''
return fq_name(self.partition, self._values['ip_intelligence_policy'])
@property @property
def security_log_profiles(self): def security_log_profiles(self):
if self._values['security_log_profiles'] is None: if self._values['security_log_profiles'] is None:
@ -2756,6 +2780,17 @@ class Difference(object):
default_persistence_profile=self.want.default_persistence_profile default_persistence_profile=self.want.default_persistence_profile
) )
@property
def ip_intelligence_policy(self):
if self.want.ip_intelligence_policy is None:
return None
if self.want.ip_intelligence_policy == '' and self.have.ip_intelligence_policy is not None:
return ""
if self.want.ip_intelligence_policy == '' and self.have.ip_intelligence_policy is None:
return None
if self.want.ip_intelligence_policy != self.have.ip_intelligence_policy:
return self.want.ip_intelligence_policy
@property @property
def policies(self): def policies(self):
if self.want.policies is None: if self.want.policies is None:
@ -2873,12 +2908,15 @@ class ModuleManager(object):
self.have = ApiParameters(client=self.client) self.have = ApiParameters(client=self.client)
self.want = ModuleParameters(client=self.client, params=self.module.params) self.want = ModuleParameters(client=self.client, params=self.module.params)
self.changes = UsableChanges() self.changes = UsableChanges()
self.provisioned_modules = []
def exec_module(self): def exec_module(self):
changed = False changed = False
result = dict() result = dict()
state = self.want.state state = self.want.state
self.provisioned_modules = modules_provisioned(self.client)
if state in ['present', 'enabled', 'disabled']: if state in ['present', 'enabled', 'disabled']:
changed = self.present() changed = self.present()
elif state == "absent": elif state == "absent":
@ -2908,6 +2946,12 @@ class ModuleManager(object):
) )
validator.check_update() validator.check_update()
if self.want.ip_intelligence_policy is not None:
if not any(x for x in self.provisioned_modules if x in ['afm', 'asm']):
raise F5ModuleError(
"AFM must be provisioned to configure an IP Intelligence policy."
)
if not self.should_update(): if not self.should_update():
return False return False
if self.module.check_mode: if self.module.check_mode:
@ -2980,6 +3024,12 @@ class ModuleManager(object):
) )
validator.check_create() validator.check_create()
if self.want.ip_intelligence_policy is not None:
if not any(x for x in self.provisioned_modules if x in ['afm', 'asm']):
raise F5ModuleError(
"AFM must be provisioned to configure an IP Intelligence policy."
)
self._set_changed_options() self._set_changed_options()
if self.module.check_mode: if self.module.check_mode:
return True return True
@ -3139,6 +3189,7 @@ class ArgumentSpec(object):
mask=dict(), mask=dict(),
firewall_staged_policy=dict(), firewall_staged_policy=dict(),
firewall_enforced_policy=dict(), firewall_enforced_policy=dict(),
ip_intelligence_policy=dict(),
security_log_profiles=dict(type='list'), security_log_profiles=dict(type='list'),
security_nat_policy=dict( security_nat_policy=dict(
type='dict', type='dict',

View file

@ -29,20 +29,18 @@ try:
from test.units.modules.utils import set_module_args from test.units.modules.utils import set_module_args
except ImportError: except ImportError:
try: from ansible.modules.network.f5.bigip_virtual_server import ApiParameters
from ansible.modules.network.f5.bigip_virtual_server import ApiParameters from ansible.modules.network.f5.bigip_virtual_server import ModuleParameters
from ansible.modules.network.f5.bigip_virtual_server import ModuleParameters from ansible.modules.network.f5.bigip_virtual_server import ModuleManager
from ansible.modules.network.f5.bigip_virtual_server import ModuleManager from ansible.modules.network.f5.bigip_virtual_server import ArgumentSpec
from ansible.modules.network.f5.bigip_virtual_server import ArgumentSpec
# Ansible 2.8 imports # Ansible 2.8 imports
from units.compat import unittest from units.compat import unittest
from units.compat.mock import Mock from units.compat.mock import Mock
from units.compat.mock import patch from units.compat.mock import patch
from units.modules.utils import set_module_args
from units.modules.utils import set_module_args
except ImportError:
raise SkipTest("F5 Ansible modules require the f5-sdk Python library")
fixture_path = os.path.join(os.path.dirname(__file__), 'fixtures') fixture_path = os.path.join(os.path.dirname(__file__), 'fixtures')
fixture_data = {} fixture_data = {}
@ -357,6 +355,18 @@ class TestManager(unittest.TestCase):
def setUp(self): def setUp(self):
self.spec = ArgumentSpec() self.spec = ArgumentSpec()
try:
self.p1 = patch('library.modules.bigip_virtual_server.modules_provisioned')
self.m1 = self.p1.start()
self.m1.return_value = ['ltm', 'gtm', 'asm']
except Exception:
self.p1 = patch('ansible.modules.network.f5.bigip_virtual_server.modules_provisioned')
self.m1 = self.p1.start()
self.m1.return_value = ['ltm', 'gtm', 'asm']
def tearDown(self):
self.p1.stop()
def test_create_virtual_server(self, *args): def test_create_virtual_server(self, *args):
set_module_args(dict( set_module_args(dict(
all_profiles=[ all_profiles=[