Skip to content

Commit

Permalink
provider/aws: Reorganize and generalize AWS IAM policy normalization
Browse files Browse the repository at this point in the history
Earlier work in #6956 caused the IAM policy documents generated by the
aws_iam_policy_document data source to follow the normalization
conventions used by most AWS services.

However, use of this data source is optional and so hand-authored IAM
policy documents used with other resources can still suffer from
normalization issues.

By reorganizing the code a little we can make re-usable normalization and
validation functions, which we will be able to use across many different
resource implementations, pending changes in subsequent commits.

This is a continuation of initial work done by David Tolnay in issue
#7785.

This will cause some minor changes to the result of the
aws_iam_policy_document data source: string sets are now sorted in
forward lexographic order rather than reverse, and "Statements" and
"Sid" will now be omitted when empty, for consistency with all of
the other attributes.
  • Loading branch information
apparentlymart committed Aug 21, 2016
1 parent e37dbef commit 2badca3
Show file tree
Hide file tree
Showing 4 changed files with 413 additions and 70 deletions.
33 changes: 13 additions & 20 deletions builtin/providers/aws/data_source_aws_iam_policy_document.go
Original file line number Diff line number Diff line change
Expand Up @@ -112,12 +112,12 @@ func dataSourceAwsIamPolicyDocumentRead(d *schema.ResourceData, meta interface{}
}

if resources := cfgStmt["resources"].(*schema.Set).List(); len(resources) > 0 {
stmt.Resources = dataSourceAwsIamPolicyDocumentReplaceVarsInList(
stmt.Resources = dataSourceAwsIamPolicyDocumentReplaceVarsInSet(
iamPolicyDecodeConfigStringList(resources),
)
}
if resources := cfgStmt["not_resources"].(*schema.Set).List(); len(resources) > 0 {
stmt.NotResources = dataSourceAwsIamPolicyDocumentReplaceVarsInList(
stmt.NotResources = dataSourceAwsIamPolicyDocumentReplaceVarsInSet(
iamPolicyDecodeConfigStringList(resources),
)
}
Expand Down Expand Up @@ -150,52 +150,45 @@ func dataSourceAwsIamPolicyDocumentRead(d *schema.ResourceData, meta interface{}
return nil
}

func dataSourceAwsIamPolicyDocumentReplaceVarsInList(in interface{}) interface{} {
switch v := in.(type) {
case string:
return dataSourceAwsIamPolicyDocumentVarReplacer.Replace(v)
case []string:
out := make([]string, len(v))
for i, item := range v {
out[i] = dataSourceAwsIamPolicyDocumentVarReplacer.Replace(item)
}
return out
default:
panic("dataSourceAwsIamPolicyDocumentReplaceVarsInList: input not string nor []string")
func dataSourceAwsIamPolicyDocumentReplaceVarsInSet(in IAMPolicyStringSet) IAMPolicyStringSet {
out := make(IAMPolicyStringSet, len(in))
for i, item := range in {
out[i] = dataSourceAwsIamPolicyDocumentVarReplacer.Replace(item)
}
return out
}

func dataSourceAwsIamPolicyDocumentMakeConditions(in []interface{}) IAMPolicyStatementConditionSet {
out := make([]IAMPolicyStatementCondition, len(in))
out := make(IAMPolicyStatementConditionSet, len(in))
for i, itemI := range in {
item := itemI.(map[string]interface{})
out[i] = IAMPolicyStatementCondition{
Test: item["test"].(string),
Variable: item["variable"].(string),
Values: dataSourceAwsIamPolicyDocumentReplaceVarsInList(
Values: dataSourceAwsIamPolicyDocumentReplaceVarsInSet(
iamPolicyDecodeConfigStringList(
item["values"].(*schema.Set).List(),
),
),
}
}
return IAMPolicyStatementConditionSet(out)
return out
}

func dataSourceAwsIamPolicyDocumentMakePrincipals(in []interface{}) IAMPolicyStatementPrincipalSet {
out := make([]IAMPolicyStatementPrincipal, len(in))
out := make(IAMPolicyStatementPrincipalSet, len(in))
for i, itemI := range in {
item := itemI.(map[string]interface{})
out[i] = IAMPolicyStatementPrincipal{
Type: item["type"].(string),
Identifiers: dataSourceAwsIamPolicyDocumentReplaceVarsInList(
Identifiers: dataSourceAwsIamPolicyDocumentReplaceVarsInSet(
iamPolicyDecodeConfigStringList(
item["identifiers"].(*schema.Set).List(),
),
),
}
}
return IAMPolicyStatementPrincipalSet(out)
return out
}

func dataSourceAwsIamPolicyPrincipalSchema() *schema.Schema {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ data "aws_iam_policy_document" "test" {
values = [
"home/",
"home/&{aws:username}/",
"",
]
}
Expand Down Expand Up @@ -117,13 +118,12 @@ var testAccAWSIAMPolicyDocumentExpectedJSON = `{
"Sid": "1",
"Effect": "Allow",
"Action": [
"s3:ListAllMyBuckets",
"s3:GetBucketLocation"
"s3:GetBucketLocation",
"s3:ListAllMyBuckets"
],
"Resource": "arn:aws:s3:::*"
},
{
"Sid": "",
"Effect": "Allow",
"Action": "s3:ListBucket",
"Resource": "arn:aws:s3:::foo",
Expand All @@ -133,26 +133,25 @@ var testAccAWSIAMPolicyDocumentExpectedJSON = `{
"Condition": {
"StringLike": {
"s3:prefix": [
"home/${aws:username}/",
"home/"
"",
"home/",
"home/${aws:username}/"
]
}
}
},
{
"Sid": "",
"Effect": "Allow",
"Action": "s3:*",
"Resource": [
"arn:aws:s3:::foo/home/${aws:username}/*",
"arn:aws:s3:::foo/home/${aws:username}"
"arn:aws:s3:::foo/home/${aws:username}",
"arn:aws:s3:::foo/home/${aws:username}/*"
],
"Principal": {
"AWS": "arn:blahblah:example"
}
},
{
"Sid": "",
"Effect": "Deny",
"NotAction": "s3:*",
"NotResource": "arn:aws:s3:::*"
Expand Down
Loading

0 comments on commit 2badca3

Please sign in to comment.