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

[Enhancement]: Geoproximity Routing Policy in Route 53 resource. #35565

Closed
128 changes: 128 additions & 0 deletions internal/service/route53/record.go
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,7 @@ func ResourceRecord() *schema.Resource {
ConflictsWith: []string{
"failover_routing_policy",
"geolocation_routing_policy",
"geoproximity_routing_policy",
"latency_routing_policy",
"multivalue_answer_routing_policy",
"weighted_routing_policy",
Expand All @@ -139,6 +140,7 @@ func ResourceRecord() *schema.Resource {
ConflictsWith: []string{
"cidr_routing_policy",
"geolocation_routing_policy",
"geoproximity_routing_policy",
"latency_routing_policy",
"multivalue_answer_routing_policy",
"weighted_routing_policy",
Expand Down Expand Up @@ -172,6 +174,54 @@ func ResourceRecord() *schema.Resource {
ConflictsWith: []string{
"cidr_routing_policy",
"failover_routing_policy",
"geoproximity_routing_policy",
"latency_routing_policy",
"multivalue_answer_routing_policy",
"weighted_routing_policy",
},
RequiredWith: []string{"set_identifier"},
},
"geoproximity_routing_policy": {
Type: schema.TypeList,
MaxItems: 1,
Optional: true,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"awsregion": {
Type: schema.TypeString,
Optional: true,
},
"bias": {
Type: schema.TypeInt,
Optional: true,
ValidateFunc: validation.IntBetween(-99, 99),
},
"coordinates": {
Type: schema.TypeSet,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"latitude": {
Type: schema.TypeString,
Required: true,
},
"longitude": {
Type: schema.TypeString,
Required: true,
},
},
},
Optional: true,
},
"localzonegroup": {
Type: schema.TypeString,
Optional: true,
},
},
},
ConflictsWith: []string{
"cidr_routing_policy",
"failover_routing_policy",
"geolocation_routing_policy",
"latency_routing_policy",
"multivalue_answer_routing_policy",
"weighted_routing_policy",
Expand All @@ -198,6 +248,7 @@ func ResourceRecord() *schema.Resource {
"cidr_routing_policy",
"failover_routing_policy",
"geolocation_routing_policy",
"geoproximity_routing_policy",
"multivalue_answer_routing_policy",
"weighted_routing_policy",
},
Expand All @@ -210,6 +261,7 @@ func ResourceRecord() *schema.Resource {
"cidr_routing_policy",
"failover_routing_policy",
"geolocation_routing_policy",
"geoproximity_routing_policy",
"latency_routing_policy",
"weighted_routing_policy",
},
Expand Down Expand Up @@ -264,6 +316,7 @@ func ResourceRecord() *schema.Resource {
"cidr_routing_policy",
"failover_routing_policy",
"geolocation_routing_policy",
"geoproximity_routing_policy",
"latency_routing_policy",
"multivalue_answer_routing_policy",
},
Expand Down Expand Up @@ -411,6 +464,18 @@ func resourceRecordRead(ctx context.Context, d *schema.ResourceData, meta interf
}
}

if record.GeoProximityLocation != nil {
v := []map[string]interface{}{{
"awsregion": aws.StringValue(record.GeoProximityLocation.AWSRegion),
"bias": aws.Int64Value((record.GeoProximityLocation.Bias)),
"coordinates": flattenCoordinate(record.GeoProximityLocation.Coordinates),
"localzonegroup": aws.StringValue(record.GeoProximityLocation.LocalZoneGroup),
}}
if err := d.Set("geoproximity_routing_policy", v); err != nil {
return sdkdiag.AppendErrorf(diags, "setting geoproximity_routing_policy: %s", err)
}
}

if record.Region != nil {
v := []map[string]interface{}{{
"region": aws.StringValue(record.Region),
Expand Down Expand Up @@ -518,6 +583,21 @@ func resourceRecordUpdate(ctx context.Context, d *schema.ResourceData, meta inte
}
}

if v, _ := d.GetChange("geoproximity_routing_policy"); v != nil {
if o, ok := v.([]interface{}); ok {
if len(o) == 1 {
if v, ok := o[0].(map[string]interface{}); ok {
oldRec.GeoProximityLocation = &route53.GeoProximityLocation{
AWSRegion: nilString(v["awsregion"].(string)),
Bias: aws.Int64(int64(v["bias"].(int))),
Coordinates: ExpandCoordinatesValue(v["coordinates"].(*schema.Set).List()),
LocalZoneGroup: nilString(v["localzonegroup"].(string)),
}
}
}
}
}

if v, _ := d.GetChange("latency_routing_policy"); v != nil {
if o, ok := v.([]interface{}); ok {
if len(o) == 1 {
Expand Down Expand Up @@ -852,6 +932,18 @@ func expandResourceRecordSet(d *schema.ResourceData, zoneName string) *route53.R
}
}

if v, ok := d.GetOk("geoproximity_routing_policy"); ok {
geoproximityvalues := v.([]interface{})
geoproximity := geoproximityvalues[0].(map[string]interface{})

rec.GeoProximityLocation = &route53.GeoProximityLocation{
AWSRegion: nilString(geoproximity["awsregion"].(string)),
Bias: aws.Int64(int64(geoproximity["bias"].(int))),
Coordinates: ExpandCoordinatesValue(geoproximity["coordinates"].(*schema.Set).List()),
LocalZoneGroup: nilString(geoproximity["localzonegroup"].(string)),
}
}

if v, ok := d.GetOk("health_check_id"); ok {
rec.HealthCheckId = aws.String(v.(string))
}
Expand Down Expand Up @@ -918,6 +1010,22 @@ func ExpandRecordName(name, zone string) string {
return rn
}

func ExpandCoordinatesValue(tfList []interface{}) *route53.Coordinates {
if len(tfList) == 0 {
return nil
}
coordinatesvalue := &route53.Coordinates{}
for _, tfMapRaw := range tfList {
tfMap, ok := tfMapRaw.(map[string]interface{})
if !ok {
continue
}
coordinatesvalue.Latitude = aws.String(tfMap["latitude"].(string))
coordinatesvalue.Longitude = aws.String(tfMap["longitude"].(string))
}
return coordinatesvalue
}

// nilString takes a string as an argument and returns a string
// pointer. The returned pointer is nil if the string argument is
// empty. Otherwise, it is a pointer to a copy of the string.
Expand Down Expand Up @@ -957,6 +1065,26 @@ func ParseRecordID(id string) [4]string {
return [4]string{recZone, recName, recType, recSet}
}

func flattenCoordinate(coordinates *route53.Coordinates) []interface{} {
if coordinates == nil {
return nil
}
var tfList []interface{}
tfMap := map[string]interface{}{}

if v := coordinates.Latitude; v != nil {
tfMap["latitude"] = aws.StringValue(v)
}

if v := coordinates.Longitude; v != nil {
tfMap["longitude"] = aws.StringValue(v)
}

tfList = append(tfList, tfMap)

return tfList
}

func validRecordType(s string) bool {
for _, v := range route53.RRType_Values() {
if v == s {
Expand Down