diff --git a/plugins/module_utils/elbv2.py b/plugins/module_utils/elbv2.py index 2a53ce5293b..3f6b6cd3714 100644 --- a/plugins/module_utils/elbv2.py +++ b/plugins/module_utils/elbv2.py @@ -21,6 +21,31 @@ from .elb_utils import get_elb_listener +# ForwardConfig may be optional if we've got a single TargetGroupArn entry +def _prune_ForwardConfig(action): + if "ForwardConfig" in action and action['Type'] == 'forward': + if action["ForwardConfig"] == { + 'TargetGroupStickinessConfig': {'Enabled': False}, + 'TargetGroups': [{"TargetGroupArn": action["TargetGroupArn"], "Weight": 1}]}: + newAction = action.copy() + del(newAction["ForwardConfig"]) + return newAction + return action + + +# the AWS api won't return the client secret, so we'll have to remove it +# or the module will always see the new and current actions as different +# and try to apply the same config +def _prune_secret(action): + if action['Type'] == 'authenticate-oidc': + action['AuthenticateOidcConfig'].pop('ClientSecret') + return action + + +def _sort_actions(actions): + return sorted(actions, key=lambda x: x.get('Order', 0)) + + class ElasticLoadBalancerV2(object): def __init__(self, connection, module): @@ -565,31 +590,13 @@ def _compare_listener(self, current_listener, new_listener): # If the lengths of the actions are the same, we'll have to verify that the # contents of those actions are the same if len(current_listener['DefaultActions']) == len(new_listener['DefaultActions']): - # if actions have just one element, compare the contents and then update if - # they're different - if len(current_listener['DefaultActions']) == 1 and len(new_listener['DefaultActions']) == 1: - if current_listener['DefaultActions'] != new_listener['DefaultActions']: - modified_listener['DefaultActions'] = new_listener['DefaultActions'] - # if actions have multiple elements, we'll have to order them first before comparing. - # multiple actions will have an 'Order' key for this purpose - else: - current_actions_sorted = sorted(current_listener['DefaultActions'], key=lambda x: x['Order']) - new_actions_sorted = sorted(new_listener['DefaultActions'], key=lambda x: x['Order']) - - # the AWS api won't return the client secret, so we'll have to remove it - # or the module will always see the new and current actions as different - # and try to apply the same config - new_actions_sorted_no_secret = [] - for action in new_actions_sorted: - # the secret is currently only defined in the oidc config - if action['Type'] == 'authenticate-oidc': - action['AuthenticateOidcConfig'].pop('ClientSecret') - new_actions_sorted_no_secret.append(action) - else: - new_actions_sorted_no_secret.append(action) - - if current_actions_sorted != new_actions_sorted_no_secret: - modified_listener['DefaultActions'] = new_listener['DefaultActions'] + current_actions_sorted = _sort_actions(current_listener['DefaultActions']) + new_actions_sorted = _sort_actions(new_listener['DefaultActions']) + + new_actions_sorted_no_secret = [_prune_secret(i) for i in new_actions_sorted] + + if [_prune_ForwardConfig(i) for i in current_actions_sorted] != [_prune_ForwardConfig(i) for i in new_actions_sorted_no_secret]: + modified_listener['DefaultActions'] = new_listener['DefaultActions'] # If the action lengths are different, then replace with the new actions else: modified_listener['DefaultActions'] = new_listener['DefaultActions'] @@ -756,29 +763,13 @@ def _compare_rule(self, current_rule, new_rule): if len(current_rule['Actions']) == len(new_rule['Actions']): # if actions have just one element, compare the contents and then update if # they're different - if len(current_rule['Actions']) == 1 and len(new_rule['Actions']) == 1: - if current_rule['Actions'] != new_rule['Actions']: - modified_rule['Actions'] = new_rule['Actions'] - # if actions have multiple elements, we'll have to order them first before comparing. - # multiple actions will have an 'Order' key for this purpose - else: - current_actions_sorted = sorted(current_rule['Actions'], key=lambda x: x['Order']) - new_actions_sorted = sorted(new_rule['Actions'], key=lambda x: x['Order']) - - # the AWS api won't return the client secret, so we'll have to remove it - # or the module will always see the new and current actions as different - # and try to apply the same config - new_actions_sorted_no_secret = [] - for action in new_actions_sorted: - # the secret is currently only defined in the oidc config - if action['Type'] == 'authenticate-oidc': - action['AuthenticateOidcConfig'].pop('ClientSecret') - new_actions_sorted_no_secret.append(action) - else: - new_actions_sorted_no_secret.append(action) - - if current_actions_sorted != new_actions_sorted_no_secret: - modified_rule['Actions'] = new_rule['Actions'] + current_actions_sorted = _sort_actions(current_rule['Actions']) + new_actions_sorted = _sort_actions(new_rule['Actions']) + + new_actions_sorted_no_secret = [_prune_secret(i) for i in new_actions_sorted] + + if [_prune_ForwardConfig(i) for i in current_actions_sorted] != [_prune_ForwardConfig(i) for i in new_actions_sorted_no_secret]: + modified_rule['Actions'] = new_rule['Actions'] # If the action lengths are different, then replace with the new actions else: modified_rule['Actions'] = new_rule['Actions'] diff --git a/tests/unit/module_utils/test_elbv2.py b/tests/unit/module_utils/test_elbv2.py new file mode 100644 index 00000000000..dba2c129bb8 --- /dev/null +++ b/tests/unit/module_utils/test_elbv2.py @@ -0,0 +1,43 @@ +# +# (c) 2021 Red Hat Inc. +# +# This file is part of Ansible +# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type + +import ansible_collections.amazon.aws.plugins.module_utils.elbv2 as elbv2 + + +one_action = [ + { + "ForwardConfig": { + "TargetGroupStickinessConfig": {"Enabled": False}, + "TargetGroups": [ + { + "TargetGroupArn": "arn:aws:elasticloadbalancing:us-east-1:966509639900:targetgroup/my-tg-58045486/5b231e04f663ae21", + "Weight": 1, + } + ], + }, + "TargetGroupArn": "arn:aws:elasticloadbalancing:us-east-1:966509639900:targetgroup/my-tg-58045486/5b231e04f663ae21", + "Type": "forward", + } +] + + +def test__prune_ForwardConfig(): + expectation = { + "TargetGroupArn": "arn:aws:elasticloadbalancing:us-east-1:966509639900:targetgroup/my-tg-58045486/5b231e04f663ae21", + "Type": "forward", + } + assert elbv2._prune_ForwardConfig(one_action[0]) == expectation + + +def _prune_secret(): + assert elbv2._prune_secret(one_action[0]) == one_action[0] + + +def _sort_actions_one_entry(): + assert elbv2._sort_actions(one_action) == one_action