github.com/anfernee/terraform@v0.6.16-0.20160430000239-06e5085a92f2/builtin/providers/aws/cloudfront_distribution_configuration_structure.go (about) 1 // CloudFront DistributionConfig structure helpers. 2 // 3 // These functions assist in pulling in data from Terraform resource 4 // configuration for the aws_cloudfront_distribution resource, as there are 5 // several sub-fields that require their own data type, and do not necessarily 6 // 1-1 translate to resource configuration. 7 8 package aws 9 10 import ( 11 "bytes" 12 "fmt" 13 "reflect" 14 "strconv" 15 "time" 16 17 "github.com/aws/aws-sdk-go/aws" 18 "github.com/aws/aws-sdk-go/service/cloudfront" 19 "github.com/hashicorp/terraform/flatmap" 20 "github.com/hashicorp/terraform/helper/hashcode" 21 "github.com/hashicorp/terraform/helper/schema" 22 ) 23 24 // Assemble the *cloudfront.DistributionConfig variable. Calls out to various 25 // expander functions to convert attributes and sub-attributes to the various 26 // complex structures which are necessary to properly build the 27 // DistributionConfig structure. 28 // 29 // Used by the aws_cloudfront_distribution Create and Update functions. 30 func expandDistributionConfig(d *schema.ResourceData) *cloudfront.DistributionConfig { 31 distributionConfig := &cloudfront.DistributionConfig{ 32 CacheBehaviors: expandCacheBehaviors(d.Get("cache_behavior").(*schema.Set)), 33 CustomErrorResponses: expandCustomErrorResponses(d.Get("custom_error_response").(*schema.Set)), 34 DefaultCacheBehavior: expandDefaultCacheBehavior(d.Get("default_cache_behavior").(*schema.Set).List()[0].(map[string]interface{})), 35 Enabled: aws.Bool(d.Get("enabled").(bool)), 36 Origins: expandOrigins(d.Get("origin").(*schema.Set)), 37 PriceClass: aws.String(d.Get("price_class").(string)), 38 } 39 // This sets CallerReference if it's still pending computation (ie: new resource) 40 if v, ok := d.GetOk("caller_reference"); ok == false { 41 distributionConfig.CallerReference = aws.String(time.Now().Format(time.RFC3339Nano)) 42 } else { 43 distributionConfig.CallerReference = aws.String(v.(string)) 44 } 45 if v, ok := d.GetOk("comment"); ok { 46 distributionConfig.Comment = aws.String(v.(string)) 47 } else { 48 distributionConfig.Comment = aws.String("") 49 } 50 if v, ok := d.GetOk("default_root_object"); ok { 51 distributionConfig.DefaultRootObject = aws.String(v.(string)) 52 } else { 53 distributionConfig.DefaultRootObject = aws.String("") 54 } 55 if v, ok := d.GetOk("logging_config"); ok { 56 distributionConfig.Logging = expandLoggingConfig(v.(*schema.Set).List()[0].(map[string]interface{})) 57 } else { 58 distributionConfig.Logging = expandLoggingConfig(nil) 59 } 60 if v, ok := d.GetOk("aliases"); ok { 61 distributionConfig.Aliases = expandAliases(v.(*schema.Set)) 62 } else { 63 distributionConfig.Aliases = expandAliases(schema.NewSet(aliasesHash, []interface{}{})) 64 } 65 if v, ok := d.GetOk("restrictions"); ok { 66 distributionConfig.Restrictions = expandRestrictions(v.(*schema.Set).List()[0].(map[string]interface{})) 67 } 68 if v, ok := d.GetOk("viewer_certificate"); ok { 69 distributionConfig.ViewerCertificate = expandViewerCertificate(v.(*schema.Set).List()[0].(map[string]interface{})) 70 } 71 if v, ok := d.GetOk("web_acl_id"); ok { 72 distributionConfig.WebACLId = aws.String(v.(string)) 73 } else { 74 distributionConfig.WebACLId = aws.String("") 75 } 76 return distributionConfig 77 } 78 79 // Unpack the *cloudfront.DistributionConfig variable and set resource data. 80 // Calls out to flatten functions to convert the DistributionConfig 81 // sub-structures to their respective attributes in the 82 // aws_cloudfront_distribution resource. 83 // 84 // Used by the aws_cloudfront_distribution Read function. 85 func flattenDistributionConfig(d *schema.ResourceData, distributionConfig *cloudfront.DistributionConfig) error { 86 var err error 87 88 d.Set("enabled", distributionConfig.Enabled) 89 d.Set("price_class", distributionConfig.PriceClass) 90 91 err = d.Set("default_cache_behavior", flattenDefaultCacheBehavior(distributionConfig.DefaultCacheBehavior)) 92 if err != nil { 93 return err 94 } 95 err = d.Set("viewer_certificate", flattenViewerCertificate(distributionConfig.ViewerCertificate)) 96 if err != nil { 97 return err 98 } 99 100 if distributionConfig.CallerReference != nil { 101 d.Set("caller_reference", distributionConfig.CallerReference) 102 } 103 if distributionConfig.Comment != nil { 104 if *distributionConfig.Comment != "" { 105 d.Set("comment", distributionConfig.Comment) 106 } 107 } 108 if distributionConfig.DefaultRootObject != nil { 109 d.Set("default_root_object", distributionConfig.DefaultRootObject) 110 } 111 if distributionConfig.WebACLId != nil { 112 d.Set("web_acl_id", distributionConfig.WebACLId) 113 } 114 115 if distributionConfig.CustomErrorResponses != nil { 116 err = d.Set("custom_error_response", flattenCustomErrorResponses(distributionConfig.CustomErrorResponses)) 117 if err != nil { 118 return err 119 } 120 } 121 if distributionConfig.CacheBehaviors != nil { 122 err = d.Set("cache_behavior", flattenCacheBehaviors(distributionConfig.CacheBehaviors)) 123 if err != nil { 124 return err 125 } 126 } 127 if distributionConfig.Logging != nil && *distributionConfig.Logging.Enabled { 128 err = d.Set("logging_config", flattenLoggingConfig(distributionConfig.Logging)) 129 if err != nil { 130 return err 131 } 132 } 133 if distributionConfig.Aliases != nil { 134 err = d.Set("aliases", flattenAliases(distributionConfig.Aliases)) 135 if err != nil { 136 return err 137 } 138 } 139 if distributionConfig.Restrictions != nil { 140 err = d.Set("restrictions", flattenRestrictions(distributionConfig.Restrictions)) 141 if err != nil { 142 return err 143 } 144 } 145 if *distributionConfig.Origins.Quantity > 0 { 146 err = d.Set("origin", flattenOrigins(distributionConfig.Origins)) 147 if err != nil { 148 return err 149 } 150 } 151 152 return nil 153 } 154 155 func expandDefaultCacheBehavior(m map[string]interface{}) *cloudfront.DefaultCacheBehavior { 156 cb := expandCacheBehavior(m) 157 var dcb cloudfront.DefaultCacheBehavior 158 159 simpleCopyStruct(cb, &dcb) 160 return &dcb 161 } 162 163 func flattenDefaultCacheBehavior(dcb *cloudfront.DefaultCacheBehavior) *schema.Set { 164 m := make(map[string]interface{}) 165 var cb cloudfront.CacheBehavior 166 167 simpleCopyStruct(dcb, &cb) 168 m = flattenCacheBehavior(&cb) 169 return schema.NewSet(defaultCacheBehaviorHash, []interface{}{m}) 170 } 171 172 // Assemble the hash for the aws_cloudfront_distribution default_cache_behavior 173 // TypeSet attribute. 174 func defaultCacheBehaviorHash(v interface{}) int { 175 var buf bytes.Buffer 176 m := v.(map[string]interface{}) 177 buf.WriteString(fmt.Sprintf("%t-", m["compress"].(bool))) 178 buf.WriteString(fmt.Sprintf("%s-", m["viewer_protocol_policy"].(string))) 179 buf.WriteString(fmt.Sprintf("%s-", m["target_origin_id"].(string))) 180 buf.WriteString(fmt.Sprintf("%d-", forwardedValuesHash(m["forwarded_values"].(*schema.Set).List()[0].(map[string]interface{})))) 181 buf.WriteString(fmt.Sprintf("%d-", m["min_ttl"].(int))) 182 if d, ok := m["trusted_signers"]; ok { 183 for _, e := range sortInterfaceSlice(d.([]interface{})) { 184 buf.WriteString(fmt.Sprintf("%s-", e.(string))) 185 } 186 } 187 if d, ok := m["max_ttl"]; ok { 188 buf.WriteString(fmt.Sprintf("%d-", d.(int))) 189 } 190 if d, ok := m["smooth_streaming"]; ok { 191 buf.WriteString(fmt.Sprintf("%t-", d.(bool))) 192 } 193 if d, ok := m["default_ttl"]; ok { 194 buf.WriteString(fmt.Sprintf("%d-", d.(int))) 195 } 196 if d, ok := m["allowed_methods"]; ok { 197 for _, e := range sortInterfaceSlice(d.([]interface{})) { 198 buf.WriteString(fmt.Sprintf("%s-", e.(string))) 199 } 200 } 201 if d, ok := m["cached_methods"]; ok { 202 for _, e := range sortInterfaceSlice(d.([]interface{})) { 203 buf.WriteString(fmt.Sprintf("%s-", e.(string))) 204 } 205 } 206 return hashcode.String(buf.String()) 207 } 208 209 func expandCacheBehaviors(s *schema.Set) *cloudfront.CacheBehaviors { 210 var qty int64 211 var items []*cloudfront.CacheBehavior 212 for _, v := range s.List() { 213 items = append(items, expandCacheBehavior(v.(map[string]interface{}))) 214 qty++ 215 } 216 return &cloudfront.CacheBehaviors{ 217 Quantity: aws.Int64(qty), 218 Items: items, 219 } 220 } 221 222 func flattenCacheBehaviors(cbs *cloudfront.CacheBehaviors) *schema.Set { 223 s := []interface{}{} 224 for _, v := range cbs.Items { 225 s = append(s, flattenCacheBehavior(v)) 226 } 227 return schema.NewSet(cacheBehaviorHash, s) 228 } 229 230 func expandCacheBehavior(m map[string]interface{}) *cloudfront.CacheBehavior { 231 cb := &cloudfront.CacheBehavior{ 232 Compress: aws.Bool(m["compress"].(bool)), 233 ViewerProtocolPolicy: aws.String(m["viewer_protocol_policy"].(string)), 234 TargetOriginId: aws.String(m["target_origin_id"].(string)), 235 ForwardedValues: expandForwardedValues(m["forwarded_values"].(*schema.Set).List()[0].(map[string]interface{})), 236 MinTTL: aws.Int64(int64(m["min_ttl"].(int))), 237 MaxTTL: aws.Int64(int64(m["max_ttl"].(int))), 238 DefaultTTL: aws.Int64(int64(m["default_ttl"].(int))), 239 } 240 if v, ok := m["trusted_signers"]; ok { 241 cb.TrustedSigners = expandTrustedSigners(v.([]interface{})) 242 } else { 243 cb.TrustedSigners = expandTrustedSigners([]interface{}{}) 244 } 245 if v, ok := m["smooth_streaming"]; ok { 246 cb.SmoothStreaming = aws.Bool(v.(bool)) 247 } 248 if v, ok := m["allowed_methods"]; ok { 249 cb.AllowedMethods = expandAllowedMethods(v.([]interface{})) 250 } 251 if v, ok := m["cached_methods"]; ok { 252 cb.AllowedMethods.CachedMethods = expandCachedMethods(v.([]interface{})) 253 } 254 if v, ok := m["path_pattern"]; ok { 255 cb.PathPattern = aws.String(v.(string)) 256 } 257 return cb 258 } 259 260 func flattenCacheBehavior(cb *cloudfront.CacheBehavior) map[string]interface{} { 261 m := make(map[string]interface{}) 262 263 m["compress"] = *cb.Compress 264 m["viewer_protocol_policy"] = *cb.ViewerProtocolPolicy 265 m["target_origin_id"] = *cb.TargetOriginId 266 m["forwarded_values"] = schema.NewSet(forwardedValuesHash, []interface{}{flattenForwardedValues(cb.ForwardedValues)}) 267 m["min_ttl"] = int(*cb.MinTTL) 268 269 if len(cb.TrustedSigners.Items) > 0 { 270 m["trusted_signers"] = flattenTrustedSigners(cb.TrustedSigners) 271 } 272 if cb.MaxTTL != nil { 273 m["max_ttl"] = int(*cb.MaxTTL) 274 } 275 if cb.SmoothStreaming != nil { 276 m["smooth_streaming"] = *cb.SmoothStreaming 277 } 278 if cb.DefaultTTL != nil { 279 m["default_ttl"] = int(*cb.DefaultTTL) 280 } 281 if cb.AllowedMethods != nil { 282 m["allowed_methods"] = flattenAllowedMethods(cb.AllowedMethods) 283 } 284 if cb.AllowedMethods.CachedMethods != nil { 285 m["cached_methods"] = flattenCachedMethods(cb.AllowedMethods.CachedMethods) 286 } 287 if cb.PathPattern != nil { 288 m["path_pattern"] = *cb.PathPattern 289 } 290 return m 291 } 292 293 // Assemble the hash for the aws_cloudfront_distribution cache_behavior 294 // TypeSet attribute. 295 func cacheBehaviorHash(v interface{}) int { 296 var buf bytes.Buffer 297 m := v.(map[string]interface{}) 298 buf.WriteString(fmt.Sprintf("%t-", m["compress"].(bool))) 299 buf.WriteString(fmt.Sprintf("%s-", m["viewer_protocol_policy"].(string))) 300 buf.WriteString(fmt.Sprintf("%s-", m["target_origin_id"].(string))) 301 buf.WriteString(fmt.Sprintf("%d-", forwardedValuesHash(m["forwarded_values"].(*schema.Set).List()[0].(map[string]interface{})))) 302 buf.WriteString(fmt.Sprintf("%d-", m["min_ttl"].(int))) 303 if d, ok := m["trusted_signers"]; ok { 304 for _, e := range sortInterfaceSlice(d.([]interface{})) { 305 buf.WriteString(fmt.Sprintf("%s-", e.(string))) 306 } 307 } 308 if d, ok := m["max_ttl"]; ok { 309 buf.WriteString(fmt.Sprintf("%d-", d.(int))) 310 } 311 if d, ok := m["smooth_streaming"]; ok { 312 buf.WriteString(fmt.Sprintf("%t-", d.(bool))) 313 } 314 if d, ok := m["default_ttl"]; ok { 315 buf.WriteString(fmt.Sprintf("%d-", d.(int))) 316 } 317 if d, ok := m["allowed_methods"]; ok { 318 for _, e := range sortInterfaceSlice(d.([]interface{})) { 319 buf.WriteString(fmt.Sprintf("%s-", e.(string))) 320 } 321 } 322 if d, ok := m["cached_methods"]; ok { 323 for _, e := range sortInterfaceSlice(d.([]interface{})) { 324 buf.WriteString(fmt.Sprintf("%s-", e.(string))) 325 } 326 } 327 if d, ok := m["path_pattern"]; ok { 328 buf.WriteString(fmt.Sprintf("%s-", d)) 329 } 330 return hashcode.String(buf.String()) 331 } 332 333 func expandTrustedSigners(s []interface{}) *cloudfront.TrustedSigners { 334 var ts cloudfront.TrustedSigners 335 if len(s) > 0 { 336 ts.Quantity = aws.Int64(int64(len(s))) 337 ts.Items = expandStringList(s) 338 ts.Enabled = aws.Bool(true) 339 } else { 340 ts.Quantity = aws.Int64(0) 341 ts.Enabled = aws.Bool(false) 342 } 343 return &ts 344 } 345 346 func flattenTrustedSigners(ts *cloudfront.TrustedSigners) []interface{} { 347 if ts.Items != nil { 348 return flattenStringList(ts.Items) 349 } 350 return []interface{}{} 351 } 352 353 func expandForwardedValues(m map[string]interface{}) *cloudfront.ForwardedValues { 354 fv := &cloudfront.ForwardedValues{ 355 QueryString: aws.Bool(m["query_string"].(bool)), 356 } 357 if v, ok := m["cookies"]; ok { 358 fv.Cookies = expandCookiePreference(v.(*schema.Set).List()[0].(map[string]interface{})) 359 } 360 if v, ok := m["headers"]; ok { 361 fv.Headers = expandHeaders(v.([]interface{})) 362 } 363 return fv 364 } 365 366 func flattenForwardedValues(fv *cloudfront.ForwardedValues) map[string]interface{} { 367 m := make(map[string]interface{}) 368 m["query_string"] = *fv.QueryString 369 if fv.Cookies != nil { 370 m["cookies"] = schema.NewSet(cookiePreferenceHash, []interface{}{flattenCookiePreference(fv.Cookies)}) 371 } 372 if fv.Headers != nil { 373 m["headers"] = flattenHeaders(fv.Headers) 374 } 375 return m 376 } 377 378 // Assemble the hash for the aws_cloudfront_distribution forwarded_values 379 // TypeSet attribute. 380 func forwardedValuesHash(v interface{}) int { 381 var buf bytes.Buffer 382 m := v.(map[string]interface{}) 383 buf.WriteString(fmt.Sprintf("%t-", m["query_string"].(bool))) 384 if d, ok := m["cookies"]; ok { 385 buf.WriteString(fmt.Sprintf("%d-", cookiePreferenceHash(d.(*schema.Set).List()[0].(map[string]interface{})))) 386 } 387 if d, ok := m["headers"]; ok { 388 for _, e := range sortInterfaceSlice(d.([]interface{})) { 389 buf.WriteString(fmt.Sprintf("%s-", e.(string))) 390 } 391 } 392 return hashcode.String(buf.String()) 393 } 394 395 func expandHeaders(d []interface{}) *cloudfront.Headers { 396 return &cloudfront.Headers{ 397 Quantity: aws.Int64(int64(len(d))), 398 Items: expandStringList(d), 399 } 400 } 401 402 func flattenHeaders(h *cloudfront.Headers) []interface{} { 403 if h.Items != nil { 404 return flattenStringList(h.Items) 405 } 406 return []interface{}{} 407 } 408 409 func expandCookiePreference(m map[string]interface{}) *cloudfront.CookiePreference { 410 cp := &cloudfront.CookiePreference{ 411 Forward: aws.String(m["forward"].(string)), 412 } 413 if v, ok := m["whitelisted_names"]; ok { 414 cp.WhitelistedNames = expandCookieNames(v.([]interface{})) 415 } 416 return cp 417 } 418 419 func flattenCookiePreference(cp *cloudfront.CookiePreference) map[string]interface{} { 420 m := make(map[string]interface{}) 421 m["forward"] = *cp.Forward 422 if cp.WhitelistedNames != nil { 423 m["whitelisted_names"] = flattenCookieNames(cp.WhitelistedNames) 424 } 425 return m 426 } 427 428 // Assemble the hash for the aws_cloudfront_distribution cookies 429 // TypeSet attribute. 430 func cookiePreferenceHash(v interface{}) int { 431 var buf bytes.Buffer 432 m := v.(map[string]interface{}) 433 buf.WriteString(fmt.Sprintf("%s-", m["forward"].(string))) 434 if d, ok := m["whitelisted_names"]; ok { 435 for _, e := range sortInterfaceSlice(d.([]interface{})) { 436 buf.WriteString(fmt.Sprintf("%s-", e.(string))) 437 } 438 } 439 return hashcode.String(buf.String()) 440 } 441 442 func expandCookieNames(d []interface{}) *cloudfront.CookieNames { 443 return &cloudfront.CookieNames{ 444 Quantity: aws.Int64(int64(len(d))), 445 Items: expandStringList(d), 446 } 447 } 448 449 func flattenCookieNames(cn *cloudfront.CookieNames) []interface{} { 450 if cn.Items != nil { 451 return flattenStringList(cn.Items) 452 } 453 return []interface{}{} 454 } 455 456 func expandAllowedMethods(s []interface{}) *cloudfront.AllowedMethods { 457 return &cloudfront.AllowedMethods{ 458 Quantity: aws.Int64(int64(len(s))), 459 Items: expandStringList(s), 460 } 461 } 462 463 func flattenAllowedMethods(am *cloudfront.AllowedMethods) []interface{} { 464 if am.Items != nil { 465 return flattenStringList(am.Items) 466 } 467 return []interface{}{} 468 } 469 470 func expandCachedMethods(s []interface{}) *cloudfront.CachedMethods { 471 return &cloudfront.CachedMethods{ 472 Quantity: aws.Int64(int64(len(s))), 473 Items: expandStringList(s), 474 } 475 } 476 477 func flattenCachedMethods(cm *cloudfront.CachedMethods) []interface{} { 478 if cm.Items != nil { 479 return flattenStringList(cm.Items) 480 } 481 return []interface{}{} 482 } 483 484 func expandOrigins(s *schema.Set) *cloudfront.Origins { 485 qty := 0 486 items := []*cloudfront.Origin{} 487 for _, v := range s.List() { 488 items = append(items, expandOrigin(v.(map[string]interface{}))) 489 qty++ 490 } 491 return &cloudfront.Origins{ 492 Quantity: aws.Int64(int64(qty)), 493 Items: items, 494 } 495 } 496 497 func flattenOrigins(ors *cloudfront.Origins) *schema.Set { 498 s := []interface{}{} 499 for _, v := range ors.Items { 500 s = append(s, flattenOrigin(v)) 501 } 502 return schema.NewSet(originHash, s) 503 } 504 505 func expandOrigin(m map[string]interface{}) *cloudfront.Origin { 506 origin := &cloudfront.Origin{ 507 Id: aws.String(m["origin_id"].(string)), 508 DomainName: aws.String(m["domain_name"].(string)), 509 } 510 if v, ok := m["custom_header"]; ok { 511 origin.CustomHeaders = expandCustomHeaders(v.(*schema.Set)) 512 } 513 if v, ok := m["custom_origin_config"]; ok { 514 if s := v.(*schema.Set).List(); len(s) > 0 { 515 origin.CustomOriginConfig = expandCustomOriginConfig(s[0].(map[string]interface{})) 516 } 517 } 518 if v, ok := m["origin_path"]; ok { 519 origin.OriginPath = aws.String(v.(string)) 520 } 521 if v, ok := m["s3_origin_config"]; ok { 522 if s := v.(*schema.Set).List(); len(s) > 0 { 523 origin.S3OriginConfig = expandS3OriginConfig(s[0].(map[string]interface{})) 524 } 525 } 526 return origin 527 } 528 529 func flattenOrigin(or *cloudfront.Origin) map[string]interface{} { 530 m := make(map[string]interface{}) 531 m["origin_id"] = *or.Id 532 m["domain_name"] = *or.DomainName 533 if or.CustomHeaders != nil { 534 m["custom_header"] = flattenCustomHeaders(or.CustomHeaders) 535 } 536 if or.CustomOriginConfig != nil { 537 m["custom_origin_config"] = schema.NewSet(customOriginConfigHash, []interface{}{flattenCustomOriginConfig(or.CustomOriginConfig)}) 538 } 539 if or.OriginPath != nil { 540 m["origin_path"] = *or.OriginPath 541 } 542 if or.S3OriginConfig != nil { 543 m["s3_origin_config"] = schema.NewSet(s3OriginConfigHash, []interface{}{flattenS3OriginConfig(or.S3OriginConfig)}) 544 } 545 return m 546 } 547 548 // Assemble the hash for the aws_cloudfront_distribution origin 549 // TypeSet attribute. 550 func originHash(v interface{}) int { 551 var buf bytes.Buffer 552 m := v.(map[string]interface{}) 553 buf.WriteString(fmt.Sprintf("%s-", m["origin_id"].(string))) 554 buf.WriteString(fmt.Sprintf("%s-", m["domain_name"].(string))) 555 if v, ok := m["custom_header"]; ok { 556 buf.WriteString(fmt.Sprintf("%d-", customHeadersHash(v.(*schema.Set)))) 557 } 558 if v, ok := m["custom_origin_config"]; ok { 559 if s := v.(*schema.Set).List(); len(s) > 0 { 560 buf.WriteString(fmt.Sprintf("%d-", customOriginConfigHash((s[0].(map[string]interface{}))))) 561 } 562 } 563 if v, ok := m["origin_path"]; ok { 564 buf.WriteString(fmt.Sprintf("%s-", v.(string))) 565 } 566 if v, ok := m["s3_origin_config"]; ok { 567 if s := v.(*schema.Set).List(); len(s) > 0 { 568 buf.WriteString(fmt.Sprintf("%d-", s3OriginConfigHash((s[0].(map[string]interface{}))))) 569 } 570 } 571 return hashcode.String(buf.String()) 572 } 573 574 func expandCustomHeaders(s *schema.Set) *cloudfront.CustomHeaders { 575 qty := 0 576 items := []*cloudfront.OriginCustomHeader{} 577 for _, v := range s.List() { 578 items = append(items, expandOriginCustomHeader(v.(map[string]interface{}))) 579 qty++ 580 } 581 return &cloudfront.CustomHeaders{ 582 Quantity: aws.Int64(int64(qty)), 583 Items: items, 584 } 585 } 586 587 func flattenCustomHeaders(chs *cloudfront.CustomHeaders) *schema.Set { 588 s := []interface{}{} 589 for _, v := range chs.Items { 590 s = append(s, flattenOriginCustomHeader(v)) 591 } 592 return schema.NewSet(originCustomHeaderHash, s) 593 } 594 595 func expandOriginCustomHeader(m map[string]interface{}) *cloudfront.OriginCustomHeader { 596 return &cloudfront.OriginCustomHeader{ 597 HeaderName: aws.String(m["name"].(string)), 598 HeaderValue: aws.String(m["value"].(string)), 599 } 600 } 601 602 func flattenOriginCustomHeader(och *cloudfront.OriginCustomHeader) map[string]interface{} { 603 return map[string]interface{}{ 604 "name": *och.HeaderName, 605 "value": *och.HeaderValue, 606 } 607 } 608 609 // Helper function used by originHash to get a composite hash for all 610 // aws_cloudfront_distribution custom_header attributes. 611 func customHeadersHash(s *schema.Set) int { 612 var buf bytes.Buffer 613 for _, v := range s.List() { 614 buf.WriteString(fmt.Sprintf("%d-", originCustomHeaderHash(v))) 615 } 616 return hashcode.String(buf.String()) 617 } 618 619 // Assemble the hash for the aws_cloudfront_distribution custom_header 620 // TypeSet attribute. 621 func originCustomHeaderHash(v interface{}) int { 622 var buf bytes.Buffer 623 m := v.(map[string]interface{}) 624 buf.WriteString(fmt.Sprintf("%s-", m["name"].(string))) 625 buf.WriteString(fmt.Sprintf("%s-", m["value"].(string))) 626 return hashcode.String(buf.String()) 627 } 628 629 func expandCustomOriginConfig(m map[string]interface{}) *cloudfront.CustomOriginConfig { 630 return &cloudfront.CustomOriginConfig{ 631 OriginProtocolPolicy: aws.String(m["origin_protocol_policy"].(string)), 632 HTTPPort: aws.Int64(int64(m["http_port"].(int))), 633 HTTPSPort: aws.Int64(int64(m["https_port"].(int))), 634 OriginSslProtocols: expandCustomOriginConfigSSL(m["origin_ssl_protocols"].([]interface{})), 635 } 636 } 637 638 func flattenCustomOriginConfig(cor *cloudfront.CustomOriginConfig) map[string]interface{} { 639 return map[string]interface{}{ 640 "origin_protocol_policy": *cor.OriginProtocolPolicy, 641 "http_port": int(*cor.HTTPPort), 642 "https_port": int(*cor.HTTPSPort), 643 "origin_ssl_protocols": flattenCustomOriginConfigSSL(cor.OriginSslProtocols), 644 } 645 } 646 647 // Assemble the hash for the aws_cloudfront_distribution custom_origin_config 648 // TypeSet attribute. 649 func customOriginConfigHash(v interface{}) int { 650 var buf bytes.Buffer 651 m := v.(map[string]interface{}) 652 buf.WriteString(fmt.Sprintf("%s-", m["origin_protocol_policy"].(string))) 653 buf.WriteString(fmt.Sprintf("%d-", m["http_port"].(int))) 654 buf.WriteString(fmt.Sprintf("%d-", m["https_port"].(int))) 655 for _, v := range sortInterfaceSlice(m["origin_ssl_protocols"].([]interface{})) { 656 buf.WriteString(fmt.Sprintf("%s-", v.(string))) 657 } 658 return hashcode.String(buf.String()) 659 } 660 661 func expandCustomOriginConfigSSL(s []interface{}) *cloudfront.OriginSslProtocols { 662 items := expandStringList(s) 663 return &cloudfront.OriginSslProtocols{ 664 Quantity: aws.Int64(int64(len(items))), 665 Items: items, 666 } 667 } 668 669 func flattenCustomOriginConfigSSL(osp *cloudfront.OriginSslProtocols) []interface{} { 670 return flattenStringList(osp.Items) 671 } 672 673 func expandS3OriginConfig(m map[string]interface{}) *cloudfront.S3OriginConfig { 674 return &cloudfront.S3OriginConfig{ 675 OriginAccessIdentity: aws.String(m["origin_access_identity"].(string)), 676 } 677 } 678 679 func flattenS3OriginConfig(s3o *cloudfront.S3OriginConfig) map[string]interface{} { 680 return map[string]interface{}{ 681 "origin_access_identity": *s3o.OriginAccessIdentity, 682 } 683 } 684 685 // Assemble the hash for the aws_cloudfront_distribution s3_origin_config 686 // TypeSet attribute. 687 func s3OriginConfigHash(v interface{}) int { 688 var buf bytes.Buffer 689 m := v.(map[string]interface{}) 690 buf.WriteString(fmt.Sprintf("%s-", m["origin_access_identity"].(string))) 691 return hashcode.String(buf.String()) 692 } 693 694 func expandCustomErrorResponses(s *schema.Set) *cloudfront.CustomErrorResponses { 695 qty := 0 696 items := []*cloudfront.CustomErrorResponse{} 697 for _, v := range s.List() { 698 items = append(items, expandCustomErrorResponse(v.(map[string]interface{}))) 699 qty++ 700 } 701 return &cloudfront.CustomErrorResponses{ 702 Quantity: aws.Int64(int64(qty)), 703 Items: items, 704 } 705 } 706 707 func flattenCustomErrorResponses(ers *cloudfront.CustomErrorResponses) *schema.Set { 708 s := []interface{}{} 709 for _, v := range ers.Items { 710 s = append(s, flattenCustomErrorResponse(v)) 711 } 712 return schema.NewSet(customErrorResponseHash, s) 713 } 714 715 func expandCustomErrorResponse(m map[string]interface{}) *cloudfront.CustomErrorResponse { 716 er := cloudfront.CustomErrorResponse{ 717 ErrorCode: aws.Int64(int64(m["error_code"].(int))), 718 } 719 if v, ok := m["error_caching_min_ttl"]; ok { 720 er.ErrorCachingMinTTL = aws.Int64(int64(v.(int))) 721 } 722 if v, ok := m["response_code"]; ok && v.(int) != 0 { 723 er.ResponseCode = aws.String(strconv.Itoa(v.(int))) 724 } else { 725 er.ResponseCode = aws.String("") 726 } 727 if v, ok := m["response_page_path"]; ok { 728 er.ResponsePagePath = aws.String(v.(string)) 729 } 730 731 return &er 732 } 733 734 func flattenCustomErrorResponse(er *cloudfront.CustomErrorResponse) map[string]interface{} { 735 m := make(map[string]interface{}) 736 m["error_code"] = int(*er.ErrorCode) 737 if er.ErrorCachingMinTTL != nil { 738 m["error_caching_min_ttl"] = int(*er.ErrorCachingMinTTL) 739 } 740 if er.ResponseCode != nil { 741 m["response_code"], _ = strconv.Atoi(*er.ResponseCode) 742 } 743 if er.ResponsePagePath != nil { 744 m["response_page_path"] = *er.ResponsePagePath 745 } 746 return m 747 } 748 749 // Assemble the hash for the aws_cloudfront_distribution custom_error_response 750 // TypeSet attribute. 751 func customErrorResponseHash(v interface{}) int { 752 var buf bytes.Buffer 753 m := v.(map[string]interface{}) 754 buf.WriteString(fmt.Sprintf("%d-", m["error_code"].(int))) 755 if v, ok := m["error_caching_min_ttl"]; ok { 756 buf.WriteString(fmt.Sprintf("%d-", v.(int))) 757 } 758 if v, ok := m["response_code"]; ok { 759 buf.WriteString(fmt.Sprintf("%d-", v.(int))) 760 } 761 if v, ok := m["response_page_path"]; ok { 762 buf.WriteString(fmt.Sprintf("%s-", v.(string))) 763 } 764 return hashcode.String(buf.String()) 765 } 766 767 func expandLoggingConfig(m map[string]interface{}) *cloudfront.LoggingConfig { 768 var lc cloudfront.LoggingConfig 769 if m != nil { 770 lc.Prefix = aws.String(m["prefix"].(string)) 771 lc.Bucket = aws.String(m["bucket"].(string)) 772 lc.IncludeCookies = aws.Bool(m["include_cookies"].(bool)) 773 lc.Enabled = aws.Bool(true) 774 } else { 775 lc.Prefix = aws.String("") 776 lc.Bucket = aws.String("") 777 lc.IncludeCookies = aws.Bool(false) 778 lc.Enabled = aws.Bool(false) 779 } 780 return &lc 781 } 782 783 func flattenLoggingConfig(lc *cloudfront.LoggingConfig) *schema.Set { 784 m := make(map[string]interface{}) 785 m["prefix"] = *lc.Prefix 786 m["bucket"] = *lc.Bucket 787 m["include_cookies"] = *lc.IncludeCookies 788 return schema.NewSet(loggingConfigHash, []interface{}{m}) 789 } 790 791 // Assemble the hash for the aws_cloudfront_distribution logging_config 792 // TypeSet attribute. 793 func loggingConfigHash(v interface{}) int { 794 var buf bytes.Buffer 795 m := v.(map[string]interface{}) 796 buf.WriteString(fmt.Sprintf("%s-", m["prefix"].(string))) 797 buf.WriteString(fmt.Sprintf("%s-", m["bucket"].(string))) 798 buf.WriteString(fmt.Sprintf("%t-", m["include_cookies"].(bool))) 799 return hashcode.String(buf.String()) 800 } 801 802 func expandAliases(as *schema.Set) *cloudfront.Aliases { 803 s := as.List() 804 var aliases cloudfront.Aliases 805 if len(s) > 0 { 806 aliases.Quantity = aws.Int64(int64(len(s))) 807 aliases.Items = expandStringList(s) 808 } else { 809 aliases.Quantity = aws.Int64(0) 810 } 811 return &aliases 812 } 813 814 func flattenAliases(aliases *cloudfront.Aliases) *schema.Set { 815 if aliases.Items != nil { 816 return schema.NewSet(aliasesHash, flattenStringList(aliases.Items)) 817 } 818 return schema.NewSet(aliasesHash, []interface{}{}) 819 } 820 821 // Assemble the hash for the aws_cloudfront_distribution aliases 822 // TypeSet attribute. 823 func aliasesHash(v interface{}) int { 824 return hashcode.String(v.(string)) 825 } 826 827 func expandRestrictions(m map[string]interface{}) *cloudfront.Restrictions { 828 return &cloudfront.Restrictions{ 829 GeoRestriction: expandGeoRestriction(m["geo_restriction"].(*schema.Set).List()[0].(map[string]interface{})), 830 } 831 } 832 833 func flattenRestrictions(r *cloudfront.Restrictions) *schema.Set { 834 m := make(map[string]interface{}) 835 s := schema.NewSet(geoRestrictionHash, []interface{}{flattenGeoRestriction(r.GeoRestriction)}) 836 m["geo_restriction"] = s 837 return schema.NewSet(restrictionsHash, []interface{}{m}) 838 } 839 840 // Assemble the hash for the aws_cloudfront_distribution restrictions 841 // TypeSet attribute. 842 func restrictionsHash(v interface{}) int { 843 var buf bytes.Buffer 844 m := v.(map[string]interface{}) 845 buf.WriteString(fmt.Sprintf("%d-", geoRestrictionHash(m["geo_restriction"].(*schema.Set).List()[0].(map[string]interface{})))) 846 return hashcode.String(buf.String()) 847 } 848 849 func expandGeoRestriction(m map[string]interface{}) *cloudfront.GeoRestriction { 850 gr := cloudfront.GeoRestriction{ 851 RestrictionType: aws.String(m["restriction_type"].(string)), 852 } 853 if v, ok := m["locations"]; ok { 854 gr.Quantity = aws.Int64(int64(len(v.([]interface{})))) 855 gr.Items = expandStringList(v.([]interface{})) 856 } else { 857 gr.Quantity = aws.Int64(0) 858 } 859 return &gr 860 } 861 862 func flattenGeoRestriction(gr *cloudfront.GeoRestriction) map[string]interface{} { 863 m := make(map[string]interface{}) 864 865 m["restriction_type"] = *gr.RestrictionType 866 if gr.Items != nil { 867 m["locations"] = flattenStringList(gr.Items) 868 } 869 return m 870 } 871 872 // Assemble the hash for the aws_cloudfront_distribution geo_restriction 873 // TypeSet attribute. 874 func geoRestrictionHash(v interface{}) int { 875 var buf bytes.Buffer 876 m := v.(map[string]interface{}) 877 // All keys added in alphabetical order. 878 buf.WriteString(fmt.Sprintf("%s-", m["restriction_type"].(string))) 879 if v, ok := m["locations"]; ok { 880 for _, w := range sortInterfaceSlice(v.([]interface{})) { 881 buf.WriteString(fmt.Sprintf("%s-", w.(string))) 882 } 883 } 884 return hashcode.String(buf.String()) 885 } 886 887 func expandViewerCertificate(m map[string]interface{}) *cloudfront.ViewerCertificate { 888 var vc cloudfront.ViewerCertificate 889 if v, ok := m["iam_certificate_id"]; ok && v != "" { 890 vc.IAMCertificateId = aws.String(v.(string)) 891 vc.SSLSupportMethod = aws.String(m["ssl_support_method"].(string)) 892 } else if v, ok := m["acm_certificate_arn"]; ok && v != "" { 893 vc.ACMCertificateArn = aws.String(v.(string)) 894 vc.SSLSupportMethod = aws.String(m["ssl_support_method"].(string)) 895 } else { 896 vc.CloudFrontDefaultCertificate = aws.Bool(m["cloudfront_default_certificate"].(bool)) 897 } 898 if v, ok := m["minimum_protocol_version"]; ok && v != "" { 899 vc.MinimumProtocolVersion = aws.String(v.(string)) 900 } 901 return &vc 902 } 903 904 func flattenViewerCertificate(vc *cloudfront.ViewerCertificate) *schema.Set { 905 m := make(map[string]interface{}) 906 907 if vc.IAMCertificateId != nil { 908 m["iam_certificate_id"] = *vc.IAMCertificateId 909 m["ssl_support_method"] = *vc.SSLSupportMethod 910 } 911 if vc.ACMCertificateArn != nil { 912 m["acm_certificate_arn"] = *vc.ACMCertificateArn 913 m["ssl_support_method"] = *vc.SSLSupportMethod 914 } 915 if vc.CloudFrontDefaultCertificate != nil { 916 m["cloudfront_default_certificate"] = *vc.CloudFrontDefaultCertificate 917 } 918 if vc.MinimumProtocolVersion != nil { 919 m["minimum_protocol_version"] = *vc.MinimumProtocolVersion 920 } 921 return schema.NewSet(viewerCertificateHash, []interface{}{m}) 922 } 923 924 // Assemble the hash for the aws_cloudfront_distribution viewer_certificate 925 // TypeSet attribute. 926 func viewerCertificateHash(v interface{}) int { 927 var buf bytes.Buffer 928 m := v.(map[string]interface{}) 929 if v, ok := m["iam_certificate_id"]; ok && v.(string) != "" { 930 buf.WriteString(fmt.Sprintf("%s-", v.(string))) 931 buf.WriteString(fmt.Sprintf("%s-", m["ssl_support_method"].(string))) 932 } else if v, ok := m["acm_certificate_arn"]; ok && v.(string) != "" { 933 buf.WriteString(fmt.Sprintf("%s-", v.(string))) 934 buf.WriteString(fmt.Sprintf("%s-", m["ssl_support_method"].(string))) 935 } else { 936 buf.WriteString(fmt.Sprintf("%t-", m["cloudfront_default_certificate"].(bool))) 937 } 938 if v, ok := m["minimum_protocol_version"]; ok && v.(string) != "" { 939 buf.WriteString(fmt.Sprintf("%s-", v.(string))) 940 } 941 return hashcode.String(buf.String()) 942 } 943 944 // Do a top-level copy of struct fields from one struct to another. Used to 945 // copy fields between CacheBehavior and DefaultCacheBehavior structs. 946 func simpleCopyStruct(src, dst interface{}) { 947 s := reflect.ValueOf(src).Elem() 948 d := reflect.ValueOf(dst).Elem() 949 950 for i := 0; i < s.NumField(); i++ { 951 if s.Field(i).CanSet() == true { 952 if s.Field(i).Interface() != nil { 953 for j := 0; j < d.NumField(); j++ { 954 if d.Type().Field(j).Name == s.Type().Field(i).Name { 955 d.Field(j).Set(s.Field(i)) 956 } 957 } 958 } 959 } 960 } 961 } 962 963 // Convert *cloudfront.ActiveTrustedSigners to a flatmap.Map type, which ensures 964 // it can probably be inserted into the schema.TypeMap type used by the 965 // active_trusted_signers attribute. 966 func flattenActiveTrustedSigners(ats *cloudfront.ActiveTrustedSigners) flatmap.Map { 967 m := make(map[string]interface{}) 968 s := []interface{}{} 969 m["enabled"] = *ats.Enabled 970 971 for _, v := range ats.Items { 972 signer := make(map[string]interface{}) 973 signer["aws_account_number"] = *v.AwsAccountNumber 974 signer["key_pair_ids"] = aws.StringValueSlice(v.KeyPairIds.Items) 975 s = append(s, signer) 976 } 977 m["items"] = s 978 return flatmap.Flatten(m) 979 }