Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

CloudFront Origin Request Policy #17342

Merged
merged 10 commits into from
Feb 4, 2021
4 changes: 4 additions & 0 deletions aws/cloudfront_distribution_configuration_structure.go
Original file line number Diff line number Diff line change
Expand Up @@ -195,6 +195,7 @@ func expandCloudFrontDefaultCacheBehavior(m map[string]interface{}) *cloudfront.
ForwardedValues: expandForwardedValues(m["forwarded_values"].([]interface{})[0].(map[string]interface{})),
MaxTTL: aws.Int64(int64(m["max_ttl"].(int))),
MinTTL: aws.Int64(int64(m["min_ttl"].(int))),
OriginRequestPolicyId: aws.String(m["origin_request_policy_id"].(string)),
TargetOriginId: aws.String(m["target_origin_id"].(string)),
ViewerProtocolPolicy: aws.String(m["viewer_protocol_policy"].(string)),
}
Expand Down Expand Up @@ -230,6 +231,7 @@ func expandCacheBehavior(m map[string]interface{}) *cloudfront.CacheBehavior {
ForwardedValues: expandForwardedValues(m["forwarded_values"].([]interface{})[0].(map[string]interface{})),
MaxTTL: aws.Int64(int64(m["max_ttl"].(int))),
MinTTL: aws.Int64(int64(m["min_ttl"].(int))),
OriginRequestPolicyId: aws.String(m["origin_request_policy_id"].(string)),
TargetOriginId: aws.String(m["target_origin_id"].(string)),
ViewerProtocolPolicy: aws.String(m["viewer_protocol_policy"].(string)),
}
Expand Down Expand Up @@ -266,6 +268,7 @@ func flattenCloudFrontDefaultCacheBehavior(dcb *cloudfront.DefaultCacheBehavior)
"viewer_protocol_policy": aws.StringValue(dcb.ViewerProtocolPolicy),
"target_origin_id": aws.StringValue(dcb.TargetOriginId),
"min_ttl": aws.Int64Value(dcb.MinTTL),
"origin_request_policy_id": aws.StringValue(dcb.OriginRequestPolicyId),
}

if dcb.ForwardedValues != nil {
Expand Down Expand Up @@ -304,6 +307,7 @@ func flattenCacheBehavior(cb *cloudfront.CacheBehavior) map[string]interface{} {
m["viewer_protocol_policy"] = aws.StringValue(cb.ViewerProtocolPolicy)
m["target_origin_id"] = aws.StringValue(cb.TargetOriginId)
m["min_ttl"] = int(aws.Int64Value(cb.MinTTL))
m["origin_request_policy_id"] = aws.StringValue(cb.OriginRequestPolicyId)

if cb.ForwardedValues != nil {
m["forwarded_values"] = []interface{}{flattenForwardedValues(cb.ForwardedValues)}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ func defaultCacheBehaviorConf() map[string]interface{} {
"smooth_streaming": false,
"default_ttl": 86400,
"allowed_methods": allowedMethodsConf(),
"origin_request_policy_id": "ABCD1234",
"cached_methods": cachedMethodsConf(),
"compress": true,
"field_level_encryption_id": "",
Expand Down
178 changes: 178 additions & 0 deletions aws/cloudfront_origin_request_policy_structure.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,178 @@
package aws

import (
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/service/cloudfront"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
)

func expandCloudFrontOriginRequestPolicyCookieNames(cookieNamesFlat map[string]interface{}) *cloudfront.CookieNames {
cookieNames := &cloudfront.CookieNames{}

var newCookieItems []*string
for _, cookie := range cookieNamesFlat["items"].(*schema.Set).List() {
newCookieItems = append(newCookieItems, aws.String(cookie.(string)))
}
cookieNames.Items = newCookieItems
cookieNames.Quantity = aws.Int64(int64(len(newCookieItems)))

return cookieNames
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
func expandCloudFrontOriginRequestPolicyCookieNames(cookieNamesFlat map[string]interface{}) *cloudfront.CookieNames {
cookieNames := &cloudfront.CookieNames{}
var newCookieItems []*string
for _, cookie := range cookieNamesFlat["items"].(*schema.Set).List() {
newCookieItems = append(newCookieItems, aws.String(cookie.(string)))
}
cookieNames.Items = newCookieItems
cookieNames.Quantity = aws.Int64(int64(len(newCookieItems)))
return cookieNames
}
func expandCloudFrontOriginRequestPolicyCookieNames(tfMap map[string]interface{}) *cloudfront.CookieNames {
if tfMap == nil {
return ni
}
apiObject := &cloudfront.CookieNames{}
var items []*string
for _, item := range tfMap["items"].(*schema.Set).List() {
items = append(items, aws.String(item.(string)))
}
apiObject.Items = items
apiObject.Quantity = aws.Int64(int64(len(items)))
return apiObject
}
  1. Include a safety nil check. If Go hits the type cast on line 13 old/17 new and cookieNamesFlat is nil, it will panic. Even though with your current setup, nil would not be possible, in the future if things change, it protects us. Since expand funcs should usually have the check, it's more likely someone would assume it's there.
  2. Expand and flatten funcs are exceptions to the descriptive variables names rule. Keeping the names generic helps future contributors to quickly mentally process flatteners/expanders.

These changes should be made to all 10 of the expanders/flatteners. See https://github.com/hashicorp/terraform-provider-aws/blob/master/docs/contributing/data-handling-and-conversion.md#expand-functions-for-blocks for more.


func expandCloudFrontOriginRequestPolicyCookiesConfig(cookiesConfigFlat map[string]interface{}) *cloudfront.OriginRequestPolicyCookiesConfig {
var cookies *cloudfront.CookieNames

if cookiesFlat, ok := cookiesConfigFlat["cookies"].([]interface{}); ok && len(cookiesFlat) == 1 {
cookies = expandCloudFrontOriginRequestPolicyCookieNames(cookiesFlat[0].(map[string]interface{}))
} else {
cookies = nil
}

cookiesConfig := &cloudfront.OriginRequestPolicyCookiesConfig{
CookieBehavior: aws.String(cookiesConfigFlat["cookie_behavior"].(string)),
Cookies: cookies,
}

return cookiesConfig
}

func expandCloudFrontOriginRequestPolicyHeaders(headerNamesFlat map[string]interface{}) *cloudfront.Headers {
headers := &cloudfront.Headers{}

var newHeaderItems []*string
for _, header := range headerNamesFlat["items"].(*schema.Set).List() {
newHeaderItems = append(newHeaderItems, aws.String(header.(string)))
}
headers.Items = newHeaderItems
headers.Quantity = aws.Int64(int64(len(newHeaderItems)))

return headers
}

func expandCloudFrontOriginRequestPolicyHeadersConfig(headersConfigFlat map[string]interface{}) *cloudfront.OriginRequestPolicyHeadersConfig {
var headers *cloudfront.Headers

if headersFlat, ok := headersConfigFlat["headers"].([]interface{}); ok && len(headersFlat) == 1 && headersConfigFlat["header_behavior"] != "none" {
headers = expandCloudFrontOriginRequestPolicyHeaders(headersFlat[0].(map[string]interface{}))
} else {
headers = nil
}

headersConfig := &cloudfront.OriginRequestPolicyHeadersConfig{
HeaderBehavior: aws.String(headersConfigFlat["header_behavior"].(string)),
Headers: headers,
}

return headersConfig
}

func expandCloudFrontOriginRequestPolicyQueryStringNames(queryStringNamesFlat map[string]interface{}) *cloudfront.QueryStringNames {
queryStringNames := &cloudfront.QueryStringNames{}

var newQueryStringItems []*string
for _, queryString := range queryStringNamesFlat["items"].(*schema.Set).List() {
newQueryStringItems = append(newQueryStringItems, aws.String(queryString.(string)))
}
queryStringNames.Items = newQueryStringItems
queryStringNames.Quantity = aws.Int64(int64(len(newQueryStringItems)))

return queryStringNames
}

func expandCloudFrontOriginRequestPolicyQueryStringsConfig(queryStringConfigFlat map[string]interface{}) *cloudfront.OriginRequestPolicyQueryStringsConfig {
var queryStrings *cloudfront.QueryStringNames

if queryStringFlat, ok := queryStringConfigFlat["query_strings"].([]interface{}); ok && len(queryStringFlat) == 1 {
queryStrings = expandCloudFrontOriginRequestPolicyQueryStringNames(queryStringFlat[0].(map[string]interface{}))
} else {
queryStrings = nil
}

queryStringConfig := &cloudfront.OriginRequestPolicyQueryStringsConfig{
QueryStringBehavior: aws.String(queryStringConfigFlat["query_string_behavior"].(string)),
QueryStrings: queryStrings,
}

return queryStringConfig
}

func expandCloudFrontOriginRequestPolicyConfig(d *schema.ResourceData) *cloudfront.OriginRequestPolicyConfig {

originRequestPolicy := &cloudfront.OriginRequestPolicyConfig{
Comment: aws.String(d.Get("comment").(string)),
Name: aws.String(d.Get("name").(string)),
CookiesConfig: expandCloudFrontOriginRequestPolicyCookiesConfig(d.Get("cookies_config").([]interface{})[0].(map[string]interface{})),
HeadersConfig: expandCloudFrontOriginRequestPolicyHeadersConfig(d.Get("headers_config").([]interface{})[0].(map[string]interface{})),
QueryStringsConfig: expandCloudFrontOriginRequestPolicyQueryStringsConfig(d.Get("query_strings_config").([]interface{})[0].(map[string]interface{})),
}

return originRequestPolicy
}

func flattenCloudFrontOriginRequestPolicyCookiesConfig(cookiesConfig *cloudfront.OriginRequestPolicyCookiesConfig) []map[string]interface{} {
cookiesConfigFlat := map[string]interface{}{}

cookies := []map[string]interface{}{}
if cookiesConfig.Cookies != nil {
cookies = []map[string]interface{}{
{
"items": cookiesConfig.Cookies.Items,
},
}
}

cookiesConfigFlat["cookie_behavior"] = aws.StringValue(cookiesConfig.CookieBehavior)
cookiesConfigFlat["cookies"] = cookies

return []map[string]interface{}{
cookiesConfigFlat,
}
}

func flattenCloudFrontOriginRequestPolicyHeadersConfig(headersConfig *cloudfront.OriginRequestPolicyHeadersConfig) []map[string]interface{} {
headersConfigFlat := map[string]interface{}{}

headers := []map[string]interface{}{}
if headersConfig.Headers != nil {
headers = []map[string]interface{}{
{
"items": headersConfig.Headers.Items,
},
}
}

headersConfigFlat["header_behavior"] = aws.StringValue(headersConfig.HeaderBehavior)
headersConfigFlat["headers"] = headers

return []map[string]interface{}{
headersConfigFlat,
}
}

func flattenCloudFrontOriginRequestPolicyQueryStringsConfig(queryStringsConfig *cloudfront.OriginRequestPolicyQueryStringsConfig) []map[string]interface{} {
queryStringsConfigFlat := map[string]interface{}{}

queryStrings := []map[string]interface{}{}
if queryStringsConfig.QueryStrings != nil {
queryStrings = []map[string]interface{}{
{
"items": queryStringsConfig.QueryStrings.Items,
},
}
}

queryStringsConfigFlat["query_string_behavior"] = aws.StringValue(queryStringsConfig.QueryStringBehavior)
queryStringsConfigFlat["query_strings"] = queryStrings

return []map[string]interface{}{
queryStringsConfigFlat,
}
}

func flattenCloudFrontOriginRequestPolicy(d *schema.ResourceData, originRequestPolicy *cloudfront.OriginRequestPolicyConfig) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As this is not flattening, I would not preface this function name with flatten.

However, more importantly, it's a bad idea to set these values in a separate function. It creates an extra burden later trying to figure out what the read() is doing. Even though it's redundant, these 5 d.Set() calls should be moved to the data source and resource read functions.

d.Set("comment", aws.StringValue(originRequestPolicy.Comment))
d.Set("name", aws.StringValue(originRequestPolicy.Name))
d.Set("cookies_config", flattenCloudFrontOriginRequestPolicyCookiesConfig(originRequestPolicy.CookiesConfig))
d.Set("headers_config", flattenCloudFrontOriginRequestPolicyHeadersConfig(originRequestPolicy.HeadersConfig))
d.Set("query_strings_config", flattenCloudFrontOriginRequestPolicyQueryStringsConfig(originRequestPolicy.QueryStringsConfig))
}
154 changes: 154 additions & 0 deletions aws/data_source_aws_cloudfront_origin_request_policy.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,154 @@
package aws

import (
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/service/cloudfront"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
)

func dataSourceAwsCloudFrontOriginRequestPolicy() *schema.Resource {
return &schema.Resource{
Read: dataSourceAwsCloudFrontOriginRequestPolicyRead,

Schema: map[string]*schema.Schema{
"name": {
Type: schema.TypeString,
Optional: true,
},
"id": {
Type: schema.TypeString,
Optional: true,
},
"comment": {
Type: schema.TypeString,
Computed: true,
},
"etag": {
Type: schema.TypeString,
Computed: true,
},
"cookies_config": {
Type: schema.TypeList,
Computed: true,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"cookie_behavior": {
Computed: true,
Type: schema.TypeString,
},
"cookies": {
Type: schema.TypeList,
Computed: true,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"items": {
Type: schema.TypeSet,
Computed: true,
Elem: &schema.Schema{Type: schema.TypeString},
},
},
},
},
},
},
},
"headers_config": {
Type: schema.TypeList,
Computed: true,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"header_behavior": {
Computed: true,
Type: schema.TypeString,
},
"headers": {
Type: schema.TypeList,
Computed: true,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"items": {
Type: schema.TypeSet,
Computed: true,
Elem: &schema.Schema{Type: schema.TypeString},
},
},
},
},
},
},
},
"query_strings_config": {
Type: schema.TypeList,
Computed: true,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"query_string_behavior": {
Type: schema.TypeString,
Computed: true,
},
"query_strings": {
Type: schema.TypeList,
Computed: true,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"items": {
Type: schema.TypeSet,
Computed: true,
Elem: &schema.Schema{Type: schema.TypeString},
},
},
},
},
},
},
},
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
"name": {
Type: schema.TypeString,
Optional: true,
},
"id": {
Type: schema.TypeString,
Optional: true,
},
"comment": {
Type: schema.TypeString,
Computed: true,
},
"etag": {
Type: schema.TypeString,
Computed: true,
},
"cookies_config": {
Type: schema.TypeList,
Computed: true,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"cookie_behavior": {
Computed: true,
Type: schema.TypeString,
},
"cookies": {
Type: schema.TypeList,
Computed: true,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"items": {
Type: schema.TypeSet,
Computed: true,
Elem: &schema.Schema{Type: schema.TypeString},
},
},
},
},
},
},
},
"headers_config": {
Type: schema.TypeList,
Computed: true,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"header_behavior": {
Computed: true,
Type: schema.TypeString,
},
"headers": {
Type: schema.TypeList,
Computed: true,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"items": {
Type: schema.TypeSet,
Computed: true,
Elem: &schema.Schema{Type: schema.TypeString},
},
},
},
},
},
},
},
"query_strings_config": {
Type: schema.TypeList,
Computed: true,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"query_string_behavior": {
Type: schema.TypeString,
Computed: true,
},
"query_strings": {
Type: schema.TypeList,
Computed: true,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"items": {
Type: schema.TypeSet,
Computed: true,
Elem: &schema.Schema{Type: schema.TypeString},
},
},
},
},
},
},
},
"comment": {
Type: schema.TypeString,
Computed: true,
},
"cookies_config": {
Type: schema.TypeList,
Computed: true,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"cookie_behavior": {
Computed: true,
Type: schema.TypeString,
},
"cookies": {
Type: schema.TypeList,
Computed: true,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"items": {
Type: schema.TypeSet,
Computed: true,
Elem: &schema.Schema{Type: schema.TypeString},
},
},
},
},
},
},
},
"etag": {
Type: schema.TypeString,
Computed: true,
},
"headers_config": {
Type: schema.TypeList,
Computed: true,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"header_behavior": {
Computed: true,
Type: schema.TypeString,
},
"headers": {
Type: schema.TypeList,
Computed: true,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"items": {
Type: schema.TypeSet,
Computed: true,
Elem: &schema.Schema{Type: schema.TypeString},
},
},
},
},
},
},
},
"id": {
Type: schema.TypeString,
Optional: true,
},
"name": {
Type: schema.TypeString,
Optional: true,
},
"query_strings_config": {
Type: schema.TypeList,
Computed: true,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"query_string_behavior": {
Type: schema.TypeString,
Computed: true,
},
"query_strings": {
Type: schema.TypeList,
Computed: true,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"items": {
Type: schema.TypeSet,
Computed: true,
Elem: &schema.Schema{Type: schema.TypeString},
},
},
},
},
},
},
},

Nit: Alphabetizing the arguments helps with quickly finding them in the future.

},
}
}

func dataSourceAwsCloudFrontOriginRequestPolicyFindByName(d *schema.ResourceData, conn *cloudfront.CloudFront) error {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Any non-CRUD func should come after the CRUD funcs.

var originRequestPolicy *cloudfront.OriginRequestPolicy
request := &cloudfront.ListOriginRequestPoliciesInput{}
resp, err := conn.ListOriginRequestPolicies(request)
if err != nil {
return err
}

for _, policySummary := range resp.OriginRequestPolicyList.Items {
if *policySummary.OriginRequestPolicy.OriginRequestPolicyConfig.Name == d.Get("name").(string) {
originRequestPolicy = policySummary.OriginRequestPolicy
break
}
}

if originRequestPolicy != nil {
d.SetId(aws.StringValue(originRequestPolicy.Id))
}
return nil
}

func dataSourceAwsCloudFrontOriginRequestPolicyRead(d *schema.ResourceData, meta interface{}) error {
conn := meta.(*AWSClient).cloudfrontconn

if d.Id() == "" {
if err := dataSourceAwsCloudFrontOriginRequestPolicyFindByName(d, conn); err != nil {
return err
}
}

if d.Id() != "" {
request := &cloudfront.GetOriginRequestPolicyInput{
Id: aws.String(d.Id()),
}

resp, err := conn.GetOriginRequestPolicy(request)
if err != nil {
return err
}
d.Set("etag", aws.StringValue(resp.ETag))

flattenCloudFrontOriginRequestPolicy(d, resp.OriginRequestPolicy.OriginRequestPolicyConfig)
}

return nil
}
Loading