Adds the ip_intelligence_policy parameter to vs module (#48903)
This commit is contained in:
parent
7546ebf08e
commit
8e6c3b06b8
2 changed files with 76 additions and 15 deletions
|
@ -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',
|
||||||
|
|
|
@ -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=[
|
||||||
|
|
Loading…
Reference in a new issue