fixes an issue where rule_lists were not correctly applied to the AFM policy (#58181)

This commit is contained in:
Wojciech Wypior 2019-06-25 14:25:23 +01:00 committed by Martin Krizek
parent d50ee592d0
commit d591014163

View file

@ -205,6 +205,7 @@ options:
- This parameter is mutually exclusive with many of the other individual-rule - This parameter is mutually exclusive with many of the other individual-rule
specific settings. This includes C(logging), C(action), C(source), specific settings. This includes C(logging), C(action), C(source),
C(destination), C(irule'), C(protocol) and C(logging). C(destination), C(irule'), C(protocol) and C(logging).
- This parameter is only used when C(parent_policy) is specified, otherwise it is ignored.
type: str type: str
icmp_message: icmp_message:
description: description:
@ -306,9 +307,10 @@ EXAMPLES = r'''
user: admin user: admin
delegate_to: localhost delegate_to: localhost
- name: Add a new rule that is uses an existing rule list - name: Add a new policy rule that uses an existing rule list
bigip_firewall_rule: bigip_firewall_rule:
name: foo name: foo
parent_policy: foo_policy
rule_list: rule-list1 rule_list: rule-list1
provider: provider:
password: secret password: secret
@ -456,7 +458,7 @@ logging:
type: bool type: bool
sample: yes sample: yes
rule_list: rule_list:
description: An existing rule list to use in the rule. description: An existing rule list to use in the parent policy.
returned: changed returned: changed
type: str type: str
sample: rule-list-1 sample: rule-list-1
@ -502,6 +504,7 @@ class Parameters(AnsibleF5Parameters):
'ipProtocol': 'protocol', 'ipProtocol': 'protocol',
'log': 'logging', 'log': 'logging',
'icmp': 'icmp_message', 'icmp': 'icmp_message',
'ruleList': 'rule_list'
} }
api_attributes = [ api_attributes = [
@ -515,6 +518,7 @@ class Parameters(AnsibleF5Parameters):
'icmp', 'icmp',
'action', 'action',
'description', 'description',
'ruleList',
] ]
returnables = [ returnables = [
@ -528,6 +532,7 @@ class Parameters(AnsibleF5Parameters):
'schedule', 'schedule',
'description', 'description',
'icmp_message', 'icmp_message',
'rule_list',
] ]
updatables = [ updatables = [
@ -541,6 +546,7 @@ class Parameters(AnsibleF5Parameters):
'schedule', 'schedule',
'description', 'description',
'icmp_message', 'icmp_message',
'rule_list',
] ]
protocol_map = { protocol_map = {
@ -721,6 +727,14 @@ class ModuleParameters(Parameters):
result = list(set(result)) result = list(set(result))
return result return result
@property
def rule_list(self):
if self._values['rule_list'] is None:
return None
if self._values['parent_policy'] is not None:
return fq_name(self.partition, self._values['rule_list'])
return None
class Changes(Parameters): class Changes(Parameters):
def to_return(self): def to_return(self):
@ -998,19 +1012,20 @@ class ModuleManager(object):
return self.create() return self.create()
def exists(self): def exists(self):
name = self.want.name
if self.want.parent_policy: if self.want.parent_policy:
uri = "https://{0}:{1}/mgmt/tm/security/firewall/policy/{2}/rules/{3}".format( uri = "https://{0}:{1}/mgmt/tm/security/firewall/policy/{2}/rules/{3}".format(
self.client.provider['server'], self.client.provider['server'],
self.client.provider['server_port'], self.client.provider['server_port'],
transform_name(self.want.partition, self.want.parent_policy), transform_name(self.want.partition, self.want.parent_policy),
self.want.name name.replace('/', '_')
) )
else: else:
uri = "https://{0}:{1}/mgmt/tm/security/firewall/rule-list/{2}/rules/{3}".format( uri = "https://{0}:{1}/mgmt/tm/security/firewall/rule-list/{2}/rules/{3}".format(
self.client.provider['server'], self.client.provider['server'],
self.client.provider['server_port'], self.client.provider['server_port'],
transform_name(self.want.partition, self.want.parent_rule_list), transform_name(self.want.partition, self.want.parent_rule_list),
self.want.name name.replace('/', '_')
) )
resp = self.client.api.get(uri) resp = self.client.api.get(uri)
if resp.ok: if resp.ok:
@ -1036,13 +1051,7 @@ class ModuleManager(object):
def create(self): def create(self):
self._set_changed_options() self._set_changed_options()
if self.want.rule_list is None and self.want.parent_rule_list is None: self.set_reasonable_creation_defaults()
if self.want.action is None:
self.changes.update({'action': 'reject'})
if self.want.logging is None:
self.changes.update({'logging': False})
if self.want.status is None:
self.changes.update({'status': 'enabled'})
if self.want.status == 'scheduled' and self.want.schedule is None: if self.want.status == 'scheduled' and self.want.schedule is None:
raise F5ModuleError( raise F5ModuleError(
"A 'schedule' must be specified when 'status' is 'scheduled'." "A 'schedule' must be specified when 'status' is 'scheduled'."
@ -1052,9 +1061,18 @@ class ModuleManager(object):
self.create_on_device() self.create_on_device()
return True return True
def set_reasonable_creation_defaults(self):
if self.want.action is None:
self.changes.update({'action': 'reject'})
if self.want.logging is None:
self.changes.update({'logging': False})
if self.want.status is None:
self.changes.update({'status': 'enabled'})
def create_on_device(self): def create_on_device(self):
params = self.changes.api_params() params = self.changes.api_params()
params['name'] = self.want.name name = self.want.name
params['name'] = name.replace('/', '_')
params['partition'] = self.want.partition params['partition'] = self.want.partition
params['placeAfter'] = 'last' params['placeAfter'] = 'last'
@ -1089,19 +1107,28 @@ class ModuleManager(object):
raise F5ModuleError(resp.content) raise F5ModuleError(resp.content)
def update_on_device(self): def update_on_device(self):
if self.want.parent_policy: name = self.want.name
if self.want.parent_policy and self.want.rule_list:
uri = "https://{0}:{1}/mgmt/tm/security/firewall/policy/{2}/rules/{3}".format( uri = "https://{0}:{1}/mgmt/tm/security/firewall/policy/{2}/rules/{3}".format(
self.client.provider['server'], self.client.provider['server'],
self.client.provider['server_port'], self.client.provider['server_port'],
transform_name(self.want.partition, self.want.parent_policy), transform_name(self.want.partition, self.want.parent_policy),
self.want.name name.replace('/', '_')
)
elif self.want.parent_policy:
uri = "https://{0}:{1}/mgmt/tm/security/firewall/policy/{2}/rules/{3}".format(
self.client.provider['server'],
self.client.provider['server_port'],
transform_name(self.want.partition, self.want.parent_policy),
name.replace('/', '_')
) )
else: else:
uri = "https://{0}:{1}/mgmt/tm/security/firewall/rule-list/{2}/rules/{3}".format( uri = "https://{0}:{1}/mgmt/tm/security/firewall/rule-list/{2}/rules/{3}".format(
self.client.provider['server'], self.client.provider['server'],
self.client.provider['server_port'], self.client.provider['server_port'],
transform_name(self.want.partition, self.want.parent_rule_list), transform_name(self.want.partition, self.want.parent_rule_list),
self.want.name name.replace('/', '_')
) )
if self.have.protocol not in ['icmp', 'icmpv6'] and self.changes.protocol not in ['icmp', 'icmpv6']: if self.have.protocol not in ['icmp', 'icmpv6'] and self.changes.protocol not in ['icmp', 'icmpv6']:
@ -1132,19 +1159,20 @@ class ModuleManager(object):
return False return False
def remove_from_device(self): def remove_from_device(self):
name = self.want.name
if self.want.parent_policy: if self.want.parent_policy:
uri = "https://{0}:{1}/mgmt/tm/security/firewall/policy/{2}/rules/{3}".format( uri = "https://{0}:{1}/mgmt/tm/security/firewall/policy/{2}/rules/{3}".format(
self.client.provider['server'], self.client.provider['server'],
self.client.provider['server_port'], self.client.provider['server_port'],
transform_name(self.want.partition, self.want.parent_policy), transform_name(self.want.partition, self.want.parent_policy),
self.want.name name.replace('/', '_')
) )
else: else:
uri = "https://{0}:{1}/mgmt/tm/security/firewall/rule-list/{2}/rules/{3}".format( uri = "https://{0}:{1}/mgmt/tm/security/firewall/rule-list/{2}/rules/{3}".format(
self.client.provider['server'], self.client.provider['server'],
self.client.provider['server_port'], self.client.provider['server_port'],
transform_name(self.want.partition, self.want.parent_rule_list), transform_name(self.want.partition, self.want.parent_rule_list),
self.want.name name.replace('/', '_')
) )
resp = self.client.api.delete(uri) resp = self.client.api.delete(uri)