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,7 +29,6 @@ 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
@ -41,8 +40,7 @@ except ImportError:
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=[