mirror of
https://github.com/ansible-collections/community.general.git
synced 2025-07-25 06:10:22 -07:00
Add helper function so that IAM policies can be compared for equality and update s3_bucket to take advantage of helper function
This commit is contained in:
parent
e66501b0b7
commit
62dfa2ad11
3 changed files with 79 additions and 6 deletions
47
lib/ansible/module_utils/ec2.py
Normal file → Executable file
47
lib/ansible/module_utils/ec2.py
Normal file → Executable file
|
@ -327,7 +327,6 @@ def camel_dict_to_snake_dict(camel_dict):
|
||||||
|
|
||||||
return all_cap_re.sub(r'\1_\2', s1).lower()
|
return all_cap_re.sub(r'\1_\2', s1).lower()
|
||||||
|
|
||||||
|
|
||||||
def value_is_list(camel_list):
|
def value_is_list(camel_list):
|
||||||
|
|
||||||
checked_list = []
|
checked_list = []
|
||||||
|
@ -341,7 +340,6 @@ def camel_dict_to_snake_dict(camel_dict):
|
||||||
|
|
||||||
return checked_list
|
return checked_list
|
||||||
|
|
||||||
|
|
||||||
snake_dict = {}
|
snake_dict = {}
|
||||||
for k, v in camel_dict.items():
|
for k, v in camel_dict.items():
|
||||||
if isinstance(v, dict):
|
if isinstance(v, dict):
|
||||||
|
@ -464,7 +462,6 @@ def get_ec2_security_group_ids_from_names(sec_group_list, ec2_connection, vpc_id
|
||||||
else:
|
else:
|
||||||
return sg.name
|
return sg.name
|
||||||
|
|
||||||
|
|
||||||
def get_sg_id(sg, boto3):
|
def get_sg_id(sg, boto3):
|
||||||
|
|
||||||
if boto3:
|
if boto3:
|
||||||
|
@ -472,7 +469,6 @@ def get_ec2_security_group_ids_from_names(sec_group_list, ec2_connection, vpc_id
|
||||||
else:
|
else:
|
||||||
return sg.id
|
return sg.id
|
||||||
|
|
||||||
|
|
||||||
sec_group_id_list = []
|
sec_group_id_list = []
|
||||||
|
|
||||||
if isinstance(sec_group_list, string_types):
|
if isinstance(sec_group_list, string_types):
|
||||||
|
@ -514,3 +510,46 @@ def get_ec2_security_group_ids_from_names(sec_group_list, ec2_connection, vpc_id
|
||||||
|
|
||||||
return sec_group_id_list
|
return sec_group_id_list
|
||||||
|
|
||||||
|
|
||||||
|
def sort_json_policy_dict(policy_dict):
|
||||||
|
|
||||||
|
""" Sort any lists in an IAM JSON policy so that comparison of two policies with identical values but
|
||||||
|
different orders will return true
|
||||||
|
Args:
|
||||||
|
policy_dict (dict): Dict representing IAM JSON policy.
|
||||||
|
Basic Usage:
|
||||||
|
>>> my_iam_policy = {'Principle': {'AWS':["31","7","14","101"]}
|
||||||
|
>>> sort_json_policy_dict(my_iam_policy)
|
||||||
|
Returns:
|
||||||
|
Dict: Will return a copy of the policy as a Dict but any List will be sorted
|
||||||
|
{
|
||||||
|
'Principle': {
|
||||||
|
'AWS': [ '7', '14', '31', '101' ]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
"""
|
||||||
|
|
||||||
|
def value_is_list(my_list):
|
||||||
|
|
||||||
|
checked_list = []
|
||||||
|
for item in my_list:
|
||||||
|
if isinstance(item, dict):
|
||||||
|
checked_list.append(sort_json_policy_dict(item))
|
||||||
|
elif isinstance(item, list):
|
||||||
|
checked_list.append(value_is_list(item))
|
||||||
|
else:
|
||||||
|
checked_list.append(item)
|
||||||
|
|
||||||
|
checked_list.sort()
|
||||||
|
return checked_list
|
||||||
|
|
||||||
|
ordered_policy_dict = {}
|
||||||
|
for key, value in policy_dict.items():
|
||||||
|
if isinstance(value, dict):
|
||||||
|
ordered_policy_dict[key] = sort_json_policy_dict(value)
|
||||||
|
elif isinstance(value, list):
|
||||||
|
ordered_policy_dict[key] = value_is_list(value)
|
||||||
|
else:
|
||||||
|
ordered_policy_dict[key] = value
|
||||||
|
|
||||||
|
return ordered_policy_dict
|
||||||
|
|
36
lib/ansible/modules/cloud/amazon/GUIDELINES.md
Normal file → Executable file
36
lib/ansible/modules/cloud/amazon/GUIDELINES.md
Normal file → Executable file
|
@ -233,6 +233,34 @@ result = connection.aws_call()
|
||||||
module.exit_json(changed=True, **camel_dict_to_snake_dict(result))
|
module.exit_json(changed=True, **camel_dict_to_snake_dict(result))
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### Dealing with IAM JSON policy
|
||||||
|
|
||||||
|
If your module accepts IAM JSON policies then set the type to 'json' in the module spec. For example"
|
||||||
|
|
||||||
|
```python
|
||||||
|
argument_spec.update(
|
||||||
|
dict(
|
||||||
|
policy=dict(required=False, default=None, type='json'),
|
||||||
|
)
|
||||||
|
)
|
||||||
|
```
|
||||||
|
|
||||||
|
Note that AWS is unlikely to return the policy in the same order that is was submitted. Therefore, a helper
|
||||||
|
function has been created to order policies before comparison.
|
||||||
|
|
||||||
|
```python
|
||||||
|
# Get the policy from AWS
|
||||||
|
current_policy = aws_object.get_policy()
|
||||||
|
|
||||||
|
# Compare the user submitted policy to the current policy but sort them first
|
||||||
|
if sort_json_policy_dict(user_policy) == sort_json_policy_dict(current_policy):
|
||||||
|
# Nothing to do
|
||||||
|
pass
|
||||||
|
else:
|
||||||
|
# Update the policy
|
||||||
|
aws_object.set_policy(user_policy)
|
||||||
|
```
|
||||||
|
|
||||||
### Helper functions
|
### Helper functions
|
||||||
|
|
||||||
Along with the connection functions in Ansible ec2.py module_utils, there are some other useful functions detailed below.
|
Along with the connection functions in Ansible ec2.py module_utils, there are some other useful functions detailed below.
|
||||||
|
@ -261,4 +289,10 @@ Opposite of above. Converts an Ansible dict to a boto3 tag list of dicts.
|
||||||
|
|
||||||
Pass this function a list of security group names or combination of security group names and IDs and this function will
|
Pass this function a list of security group names or combination of security group names and IDs and this function will
|
||||||
return a list of IDs. You should also pass the VPC ID if known because security group names are not necessarily unique
|
return a list of IDs. You should also pass the VPC ID if known because security group names are not necessarily unique
|
||||||
across VPCs.
|
across VPCs.
|
||||||
|
|
||||||
|
### sort_json_policy_dict
|
||||||
|
|
||||||
|
Pass any JSON policy dict to this function in order to sort any list contained therein. This is useful
|
||||||
|
because AWS rarely return lists in the same order that they were submitted so without this function, comparison
|
||||||
|
of identical policies returns false.
|
2
lib/ansible/modules/cloud/amazon/s3_bucket.py
Normal file → Executable file
2
lib/ansible/modules/cloud/amazon/s3_bucket.py
Normal file → Executable file
|
@ -213,7 +213,7 @@ def _create_or_update_bucket(connection, module, location):
|
||||||
# only show changed if there was already a policy
|
# only show changed if there was already a policy
|
||||||
changed = bool(current_policy)
|
changed = bool(current_policy)
|
||||||
|
|
||||||
elif current_policy != policy:
|
elif sort_json_policy_dict(current_policy) != sort_json_policy_dict(policy):
|
||||||
try:
|
try:
|
||||||
bucket.set_policy(json.dumps(policy))
|
bucket.set_policy(json.dumps(policy))
|
||||||
changed = True
|
changed = True
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue