Skip to content

Commit

Permalink
elbv2: action comparaison, handle ForwardConfig dict
Browse files Browse the repository at this point in the history
The `ForwardConfig` key of the action is optional. Its presence
during the `compare_listeners()` or `compare_rules()` evaluation
breaks the comparison between the expectation and current state.

With this patch, we ignore the key IF this structure is not required.

Closes: ansible-collections#218
  • Loading branch information
goneri committed Jan 15, 2021
1 parent 3ef1de8 commit cdfbb53
Show file tree
Hide file tree
Showing 2 changed files with 82 additions and 48 deletions.
87 changes: 39 additions & 48 deletions plugins/module_utils/elbv2.py
Original file line number Diff line number Diff line change
Expand Up @@ -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):
Expand Down Expand Up @@ -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']
Expand Down Expand Up @@ -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']
Expand Down
43 changes: 43 additions & 0 deletions tests/unit/module_utils/test_elbv2.py
Original file line number Diff line number Diff line change
@@ -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

0 comments on commit cdfbb53

Please sign in to comment.