Skip to content

Commit

Permalink
wafv2_rule_group - tagging (ansible-collections#1210)
Browse files Browse the repository at this point in the history
wafv2_rule_group - support for managing tags

SUMMARY

Add support for returning tags
Add support for updating tags
Add support for purge_tags
Add fix for updating description when rules don't change.
Ensure description of rule group is returned when updates happen
Split integration tests from full wafv2 tests (full tests are broken)

ISSUE TYPE

Bugfix Pull Request
Feature Pull Request

COMPONENT NAME
wafv2_rule_group
wafv2_rule_group_info
ADDITIONAL INFORMATION

Reviewed-by: Joseph Torcasso <None>
Reviewed-by: Mark Chappell <None>
  • Loading branch information
tremble authored Jun 7, 2022
1 parent ce941d9 commit 1f0c866
Show file tree
Hide file tree
Showing 2 changed files with 60 additions and 37 deletions.
77 changes: 46 additions & 31 deletions wafv2_rule_group.py
Original file line number Diff line number Diff line change
Expand Up @@ -60,10 +60,6 @@
description:
- capacity of wafv2 rule group.
type: int
tags:
description:
- tags for wafv2 rule group.
type: dict
purge_rules:
description:
- When set to C(no), keep the existing load balancer rules in place. Will modify and add, but will not delete.
Expand All @@ -73,6 +69,7 @@
extends_documentation_fragment:
- amazon.aws.aws
- amazon.aws.ec2
- amazon.aws.tags
'''

Expand Down Expand Up @@ -213,15 +210,18 @@
from ansible_collections.community.aws.plugins.module_utils.wafv2 import compare_priority_rules
from ansible_collections.community.aws.plugins.module_utils.wafv2 import wafv2_list_rule_groups
from ansible_collections.community.aws.plugins.module_utils.wafv2 import wafv2_snake_dict_to_camel_dict
from ansible_collections.community.aws.plugins.module_utils.wafv2 import describe_wafv2_tags
from ansible_collections.community.aws.plugins.module_utils.wafv2 import ensure_wafv2_tags


class RuleGroup:
def __init__(self, wafv2, name, scope, fail_json_aws):
self.wafv2 = wafv2
self.id = None
self.name = name
self.scope = scope
self.fail_json_aws = fail_json_aws
self.existing_group, self.id, self.locktoken = self.get_group()
self.existing_group = self.get_group()

def update(self, description, rules, sampled_requests, cloudwatch_metrics, metric_name):
req_obj = {
Expand All @@ -244,32 +244,38 @@ def update(self, description, rules, sampled_requests, cloudwatch_metrics, metri
response = self.wafv2.update_rule_group(**req_obj)
except (BotoCoreError, ClientError) as e:
self.fail_json_aws(e, msg="Failed to update wafv2 rule group.")
return response
return self.refresh_group()

def get_group(self):
response = self.list()
id = None
locktoken = None
arn = None
if self.id is None:
response = self.list()

for item in response.get('RuleGroups'):
if item.get('Name') == self.name:
self.id = item.get('Id')
self.locktoken = item.get('LockToken')
self.arn = item.get('ARN')

for item in response.get('RuleGroups'):
if item.get('Name') == self.name:
id = item.get('Id')
locktoken = item.get('LockToken')
arn = item.get('ARN')
return self.refresh_group()

def refresh_group(self):
existing_group = None
if id:
if self.id:
try:
existing_group = self.wafv2.get_rule_group(
response = self.wafv2.get_rule_group(
Name=self.name,
Scope=self.scope,
Id=id
Id=self.id
)
existing_group = response.get('RuleGroup')
self.locktoken = response.get('LockToken')
except (BotoCoreError, ClientError) as e:
self.fail_json_aws(e, msg="Failed to get wafv2 rule group.")

return existing_group, id, locktoken
tags = describe_wafv2_tags(self.wafv2, self.arn, self.fail_json_aws)
existing_group['tags'] = tags or {}

return existing_group

def list(self):
return wafv2_list_rule_groups(self.wafv2, self.scope, self.fail_json_aws)
Expand Down Expand Up @@ -315,7 +321,7 @@ def create(self, capacity, description, rules, sampled_requests, cloudwatch_metr
except (BotoCoreError, ClientError) as e:
self.fail_json_aws(e, msg="Failed to create wafv2 rule group.")

self.existing_group, self.id, self.locktoken = self.get_group()
self.existing_group = self.get_group()

return self.existing_group

Expand All @@ -332,8 +338,9 @@ def main():
sampled_requests=dict(type='bool', default=False),
cloudwatch_metrics=dict(type='bool', default=True),
metric_name=dict(type='str'),
tags=dict(type='dict'),
purge_rules=dict(default=True, type='bool')
tags=dict(type='dict', aliases=['resource_tags']),
purge_tags=dict(default=True, type='bool'),
purge_rules=dict(default=True, type='bool'),
)

module = AnsibleAWSModule(
Expand All @@ -352,6 +359,7 @@ def main():
cloudwatch_metrics = module.params.get("cloudwatch_metrics")
metric_name = module.params.get("metric_name")
tags = module.params.get("tags")
purge_tags = module.params.get("purge_tags")
purge_rules = module.params.get("purge_rules")
check_mode = module.check_mode

Expand All @@ -363,26 +371,33 @@ def main():
if not metric_name:
metric_name = name

rule_group = RuleGroup(module.client('wafv2'), name, scope, module.fail_json_aws)
wafv2 = module.client('wafv2')
rule_group = RuleGroup(wafv2, name, scope, module.fail_json_aws)

change = False
retval = {}

if state == 'present':
if rule_group.get():
change, rules = compare_priority_rules(rule_group.get().get('RuleGroup').get('Rules'), rules, purge_rules, state)
change = change or rule_group.get().get('RuleGroup').get('Description') != description

if change and not check_mode:
tagging_change = ensure_wafv2_tags(wafv2, rule_group.arn, tags, purge_tags,
module.fail_json_aws, module.check_mode)
rules_change, rules = compare_priority_rules(rule_group.get().get('Rules'), rules, purge_rules, state)
description_change = bool(description) and (rule_group.get().get('Description') != description)
change = tagging_change or rules_change or description_change
retval = rule_group.get()
if module.check_mode:
# In check mode nothing changes...
pass
elif rules_change or description_change:
retval = rule_group.update(
description,
rules,
sampled_requests,
cloudwatch_metrics,
metric_name
)
else:
retval = rule_group.get().get('RuleGroup')
elif tagging_change:
retval = rule_group.refresh_group()

else:
change = True
Expand All @@ -401,7 +416,7 @@ def main():
if rule_group.get():
if rules:
if len(rules) > 0:
change, rules = compare_priority_rules(rule_group.get().get('RuleGroup').get('Rules'), rules, purge_rules, state)
change, rules = compare_priority_rules(rule_group.get().get('Rules'), rules, purge_rules, state)
if change and not check_mode:
retval = rule_group.update(
description,
Expand All @@ -415,7 +430,7 @@ def main():
if not check_mode:
retval = rule_group.remove()

module.exit_json(changed=change, **camel_dict_to_snake_dict(retval))
module.exit_json(changed=change, **camel_dict_to_snake_dict(retval, ignore_list=['tags']))


if __name__ == '__main__':
Expand Down
20 changes: 14 additions & 6 deletions wafv2_rule_group_info.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,8 @@
options:
state:
description:
- Whether the rule is present or absent.
choices: ["present", "absent"]
required: true
- This option does nothing, has been deprecated, and will be removed in a release after 2022-12-01.
required: false
type: str
name:
description:
Expand All @@ -34,8 +33,8 @@
type: str
extends_documentation_fragment:
- amazon.aws.aws
- amazon.aws.ec2
- amazon.aws.aws
- amazon.aws.ec2
'''

Expand Down Expand Up @@ -102,6 +101,7 @@
from ansible_collections.amazon.aws.plugins.module_utils.core import AnsibleAWSModule
from ansible_collections.amazon.aws.plugins.module_utils.ec2 import camel_dict_to_snake_dict
from ansible_collections.community.aws.plugins.module_utils.wafv2 import wafv2_list_rule_groups
from ansible_collections.community.aws.plugins.module_utils.wafv2 import describe_wafv2_tags


def get_rule_group(wafv2, name, scope, id, fail_json_aws):
Expand All @@ -118,7 +118,7 @@ def get_rule_group(wafv2, name, scope, id, fail_json_aws):

def main():
arg_spec = dict(
state=dict(type='str', required=True, choices=['present', 'absent']),
state=dict(type='str', required=False),
name=dict(type='str', required=True),
scope=dict(type='str', required=True, choices=['CLOUDFRONT', 'REGIONAL'])
)
Expand All @@ -134,6 +134,11 @@ def main():

wafv2 = module.client('wafv2')

if state:
module.deprecate(
'The state parameter does nothing, has been deprecated, and will be removed in a future release.',
version='6.0.0', collection_name='community.aws')

# check if rule group exists
response = wafv2_list_rule_groups(wafv2, scope, module.fail_json_aws)
id = None
Expand All @@ -142,11 +147,14 @@ def main():
for item in response.get('RuleGroups'):
if item.get('Name') == name:
id = item.get('Id')
arn = item.get('ARN')

existing_group = None
if id:
existing_group = get_rule_group(wafv2, name, scope, id, module.fail_json_aws)
retval = camel_dict_to_snake_dict(existing_group.get('RuleGroup'))
tags = describe_wafv2_tags(wafv2, arn, module.fail_json_aws)
retval['tags'] = tags or {}

module.exit_json(**retval)

Expand Down

0 comments on commit 1f0c866

Please sign in to comment.