github.com/vtorhonen/terraform@v0.9.0-beta2.0.20170307220345-5d894e4ffda7/builtin/providers/aws/data_source_aws_iam_policy_document.go (about) 1 package aws 2 3 import ( 4 "fmt" 5 6 "encoding/json" 7 "strings" 8 9 "github.com/hashicorp/terraform/helper/hashcode" 10 "github.com/hashicorp/terraform/helper/schema" 11 "strconv" 12 ) 13 14 var dataSourceAwsIamPolicyDocumentVarReplacer = strings.NewReplacer("&{", "${") 15 16 func dataSourceAwsIamPolicyDocument() *schema.Resource { 17 setOfString := &schema.Schema{ 18 Type: schema.TypeSet, 19 Optional: true, 20 Elem: &schema.Schema{ 21 Type: schema.TypeString, 22 }, 23 } 24 25 return &schema.Resource{ 26 Read: dataSourceAwsIamPolicyDocumentRead, 27 28 Schema: map[string]*schema.Schema{ 29 "policy_id": { 30 Type: schema.TypeString, 31 Optional: true, 32 }, 33 "statement": { 34 Type: schema.TypeList, 35 Required: true, 36 Elem: &schema.Resource{ 37 Schema: map[string]*schema.Schema{ 38 "sid": { 39 Type: schema.TypeString, 40 Optional: true, 41 }, 42 "effect": { 43 Type: schema.TypeString, 44 Optional: true, 45 Default: "Allow", 46 ValidateFunc: func(v interface{}, k string) (ws []string, es []error) { 47 switch v.(string) { 48 case "Allow", "Deny": 49 return 50 default: 51 es = append(es, fmt.Errorf("%q must be either \"Allow\" or \"Deny\"", k)) 52 return 53 } 54 }, 55 }, 56 "actions": setOfString, 57 "not_actions": setOfString, 58 "resources": setOfString, 59 "not_resources": setOfString, 60 "principals": dataSourceAwsIamPolicyPrincipalSchema(), 61 "not_principals": dataSourceAwsIamPolicyPrincipalSchema(), 62 "condition": { 63 Type: schema.TypeSet, 64 Optional: true, 65 Elem: &schema.Resource{ 66 Schema: map[string]*schema.Schema{ 67 "test": { 68 Type: schema.TypeString, 69 Required: true, 70 }, 71 "variable": { 72 Type: schema.TypeString, 73 Required: true, 74 }, 75 "values": { 76 Type: schema.TypeSet, 77 Required: true, 78 Elem: &schema.Schema{ 79 Type: schema.TypeString, 80 }, 81 }, 82 }, 83 }, 84 }, 85 }, 86 }, 87 }, 88 "json": { 89 Type: schema.TypeString, 90 Computed: true, 91 }, 92 }, 93 } 94 } 95 96 func dataSourceAwsIamPolicyDocumentRead(d *schema.ResourceData, meta interface{}) error { 97 doc := &IAMPolicyDoc{ 98 Version: "2012-10-17", 99 } 100 101 if policyId, hasPolicyId := d.GetOk("policy_id"); hasPolicyId { 102 doc.Id = policyId.(string) 103 } 104 105 var cfgStmts = d.Get("statement").([]interface{}) 106 stmts := make([]*IAMPolicyStatement, len(cfgStmts)) 107 doc.Statements = stmts 108 for i, stmtI := range cfgStmts { 109 cfgStmt := stmtI.(map[string]interface{}) 110 stmt := &IAMPolicyStatement{ 111 Effect: cfgStmt["effect"].(string), 112 } 113 114 if sid, ok := cfgStmt["sid"]; ok { 115 stmt.Sid = sid.(string) 116 } 117 118 if actions := cfgStmt["actions"].(*schema.Set).List(); len(actions) > 0 { 119 stmt.Actions = iamPolicyDecodeConfigStringList(actions) 120 } 121 if actions := cfgStmt["not_actions"].(*schema.Set).List(); len(actions) > 0 { 122 stmt.NotActions = iamPolicyDecodeConfigStringList(actions) 123 } 124 125 if resources := cfgStmt["resources"].(*schema.Set).List(); len(resources) > 0 { 126 stmt.Resources = dataSourceAwsIamPolicyDocumentReplaceVarsInList( 127 iamPolicyDecodeConfigStringList(resources), 128 ) 129 } 130 if resources := cfgStmt["not_resources"].(*schema.Set).List(); len(resources) > 0 { 131 stmt.NotResources = dataSourceAwsIamPolicyDocumentReplaceVarsInList( 132 iamPolicyDecodeConfigStringList(resources), 133 ) 134 } 135 136 if principals := cfgStmt["principals"].(*schema.Set).List(); len(principals) > 0 { 137 stmt.Principals = dataSourceAwsIamPolicyDocumentMakePrincipals(principals) 138 } 139 140 if principals := cfgStmt["not_principals"].(*schema.Set).List(); len(principals) > 0 { 141 stmt.NotPrincipals = dataSourceAwsIamPolicyDocumentMakePrincipals(principals) 142 } 143 144 if conditions := cfgStmt["condition"].(*schema.Set).List(); len(conditions) > 0 { 145 stmt.Conditions = dataSourceAwsIamPolicyDocumentMakeConditions(conditions) 146 } 147 148 stmts[i] = stmt 149 } 150 151 jsonDoc, err := json.MarshalIndent(doc, "", " ") 152 if err != nil { 153 // should never happen if the above code is correct 154 return err 155 } 156 jsonString := string(jsonDoc) 157 158 d.Set("json", jsonString) 159 d.SetId(strconv.Itoa(hashcode.String(jsonString))) 160 161 return nil 162 } 163 164 func dataSourceAwsIamPolicyDocumentReplaceVarsInList(in interface{}) interface{} { 165 switch v := in.(type) { 166 case string: 167 return dataSourceAwsIamPolicyDocumentVarReplacer.Replace(v) 168 case []string: 169 out := make([]string, len(v)) 170 for i, item := range v { 171 out[i] = dataSourceAwsIamPolicyDocumentVarReplacer.Replace(item) 172 } 173 return out 174 default: 175 panic("dataSourceAwsIamPolicyDocumentReplaceVarsInList: input not string nor []string") 176 } 177 } 178 179 func dataSourceAwsIamPolicyDocumentMakeConditions(in []interface{}) IAMPolicyStatementConditionSet { 180 out := make([]IAMPolicyStatementCondition, len(in)) 181 for i, itemI := range in { 182 item := itemI.(map[string]interface{}) 183 out[i] = IAMPolicyStatementCondition{ 184 Test: item["test"].(string), 185 Variable: item["variable"].(string), 186 Values: dataSourceAwsIamPolicyDocumentReplaceVarsInList( 187 iamPolicyDecodeConfigStringList( 188 item["values"].(*schema.Set).List(), 189 ), 190 ), 191 } 192 } 193 return IAMPolicyStatementConditionSet(out) 194 } 195 196 func dataSourceAwsIamPolicyDocumentMakePrincipals(in []interface{}) IAMPolicyStatementPrincipalSet { 197 out := make([]IAMPolicyStatementPrincipal, len(in)) 198 for i, itemI := range in { 199 item := itemI.(map[string]interface{}) 200 out[i] = IAMPolicyStatementPrincipal{ 201 Type: item["type"].(string), 202 Identifiers: dataSourceAwsIamPolicyDocumentReplaceVarsInList( 203 iamPolicyDecodeConfigStringList( 204 item["identifiers"].(*schema.Set).List(), 205 ), 206 ), 207 } 208 } 209 return IAMPolicyStatementPrincipalSet(out) 210 } 211 212 func dataSourceAwsIamPolicyPrincipalSchema() *schema.Schema { 213 return &schema.Schema{ 214 Type: schema.TypeSet, 215 Optional: true, 216 Elem: &schema.Resource{ 217 Schema: map[string]*schema.Schema{ 218 "type": &schema.Schema{ 219 Type: schema.TypeString, 220 Required: true, 221 }, 222 "identifiers": &schema.Schema{ 223 Type: schema.TypeSet, 224 Required: true, 225 Elem: &schema.Schema{ 226 Type: schema.TypeString, 227 }, 228 }, 229 }, 230 }, 231 } 232 }