From 474dc619ba20150aa3ef25d70d7ad1c609b66b92 Mon Sep 17 00:00:00 2001 From: Tom Williams Date: Tue, 28 Feb 2017 23:54:41 -0500 Subject: [PATCH] INFRA-4445 - sort policy docs so they compare equal when they in fact are --- salt/states/boto_iam_role.py | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/salt/states/boto_iam_role.py b/salt/states/boto_iam_role.py index 97cde4faf3..aaff877547 100644 --- a/salt/states/boto_iam_role.py +++ b/salt/states/boto_iam_role.py @@ -269,11 +269,11 @@ def _role_present( if not policy_document: policy = __salt__['boto_iam.build_policy'](region, key, keyid, profile) - if role['assume_role_policy_document'] != policy: + if _sort_policy(role['assume_role_policy_document']) != _sort_policy(policy): update_needed = True _policy_document = policy else: - if role['assume_role_policy_document'] != policy_document: + if _sort_policy(role['assume_role_policy_document']) != _sort_policy(policy_document): update_needed = True _policy_document = policy_document if update_needed: @@ -357,6 +357,19 @@ def _instance_profile_associated( return ret +def _sort_policy(doc): + # List-type sub-items in policies don't happen to be order-sensitive, but + # compare operations will render them unequal, leading to non-idempotent + # state runs. We'll sort any list-type subitems before comparison to reduce + # the likelihood of false negatives. + if isinstance(doc, list): + return sorted([_sort_policy(i) for i in doc]) + elif isinstance(doc, dict): + return dict([(k, _sort_policy(v)) for k, v in doc.items()]) + else: + return doc + + def _policies_present( name, policies=None,