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

Bug: azurerm_dns_aaaa_record - Normalize IPv6 addresses #5459

Merged
merged 9 commits into from
Jan 30, 2020
Merged
Show file tree
Hide file tree
Changes from 8 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 24 additions & 0 deletions azurerm/helpers/azure/ipv6.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package azure

import (
"net"

"github.com/hashicorp/terraform-plugin-sdk/helper/hashcode"
)

// NormalizeIPv6Address returns the normalized notation of an IPv6
func NormalizeIPv6Address(ipv6 interface{}) string {
if ipv6 == nil || ipv6.(string) == "" {
return ""
}
r := net.ParseIP(ipv6.(string))
if r == nil {
return ""
}
return r.String()
}

// HashIPv6Address normalizes an IPv6 address and returns a hash for it
func HashIPv6Address(ipv6 interface{}) int {
return hashcode.String(NormalizeIPv6Address(ipv6))
}
84 changes: 84 additions & 0 deletions azurerm/helpers/azure/ipv6_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
package azure

import "testing"

func TestIPv6Compression(t *testing.T) {
cases := []struct {
Name string
Input interface{}
Output string
Valid bool
}{
{
Name: "input empty",
Input: "",
Output: "",
Valid: true,
},
{
Name: "valid IPv6 input, invalid compression",
Input: "2001:0db8:85a3:0:0:8a2e:0370:7334",
Output: "2001:0db8:85a3:0:0:8a2e:0370:7334",
Valid: false,
},
{
Name: "invalid IPv6 input",
Input: "2001::invalid",
Output: "",
Valid: false,
},
{
Name: "valid IPv6 compression",
Input: "2001:0db8:85a3:0:0:8a2e:0370:7334",
Output: "2001:db8:85a3::8a2e:370:7334",
Valid: true,
},
}

for _, tc := range cases {
t.Run(tc.Name, func(t *testing.T) {
r := NormalizeIPv6Address(tc.Input)
if (r != tc.Output) && tc.Valid {
t.Fatalf("Expected NormalizeIPv6Address to return '%q' for '%q' (got '%q')", tc.Output, tc.Input, r)
}
})
}
}

func TestHashIPv6Address(t *testing.T) {
cases := []struct {
Name string
Input interface{}
Output int
}{
{
Name: "input empty",
Input: "",
Output: 0,
},
{
Name: "uncompressed",
Input: "2001:0db8:85a3:0:0:8a2e:0370:7334",
Output: 3242211790,
},
{
Name: "invalid",
Input: "2001::invalid",
Output: 0,
},
{
Name: "compressed",
Input: "2001:db8:85a3::8a2e:370:7334",
Output: 3242211790,
},
}

for _, tc := range cases {
t.Run(tc.Name, func(t *testing.T) {
r := HashIPv6Address(tc.Input)
if r != tc.Output {
t.Fatalf("Expected HashIPv6Address to return '%d' for '%q' (got '%d')", tc.Output, tc.Input, r)
}
})
}
}
16 changes: 10 additions & 6 deletions azurerm/internal/services/dns/resource_arm_dns_aaaa_record.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (
"github.com/hashicorp/terraform-plugin-sdk/helper/schema"
"github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure"
"github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf"
"github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/validate"
"github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/clients"
"github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features"
"github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/tags"
Expand Down Expand Up @@ -48,10 +49,13 @@ func resourceArmDnsAAAARecord() *schema.Resource {
},

"records": {
Type: schema.TypeSet,
Optional: true,
Elem: &schema.Schema{Type: schema.TypeString},
Set: schema.HashString,
Type: schema.TypeSet,
Optional: true,
Elem: &schema.Schema{
Type: schema.TypeString,
ValidateFunc: validate.IPv6Address,
},
Set: azure.HashIPv6Address,
ConflictsWith: []string{"target_resource_id"},
},

Expand Down Expand Up @@ -211,7 +215,7 @@ func expandAzureRmDnsAaaaRecords(input []interface{}) *[]dns.AaaaRecord {
records := make([]dns.AaaaRecord, len(input))

for i, v := range input {
ipv6 := v.(string)
ipv6 := azure.NormalizeIPv6Address(v)
records[i] = dns.AaaaRecord{
Ipv6Address: &ipv6,
}
Expand All @@ -231,7 +235,7 @@ func flattenAzureRmDnsAaaaRecords(records *[]dns.AaaaRecord) []string {
continue
}

results = append(results, *record.Ipv6Address)
results = append(results, azure.NormalizeIPv6Address(*record.Ipv6Address))
}
return results
}
Original file line number Diff line number Diff line change
Expand Up @@ -200,6 +200,33 @@ func TestAccAzureRMDnsAaaaRecord_AliasToRecords(t *testing.T) {
})
}

func TestAccAzureRMDnsAAAARecord_uncompressed(t *testing.T) {
data := acceptance.BuildTestData(t, "azurerm_dns_aaaa_record", "test")

resource.ParallelTest(t, resource.TestCase{
PreCheck: func() { acceptance.PreCheck(t) },
Providers: acceptance.SupportedProviders,
CheckDestroy: testCheckAzureRMDnsAaaaRecordDestroy,
Steps: []resource.TestStep{
{
Config: testAccAzureRMDnsAAAARecord_uncompressed(data),
Check: resource.ComposeTestCheckFunc(
testCheckAzureRMDnsAaaaRecordExists(data.ResourceName),
resource.TestCheckResourceAttrSet(data.ResourceName, "fqdn"),
),
},
{
Config: testAccAzureRMDnsAAAARecord_uncompressed(data), // just use the same for updating
Check: resource.ComposeTestCheckFunc(
testCheckAzureRMDnsAaaaRecordExists(data.ResourceName),
resource.TestCheckResourceAttr(data.ResourceName, "records.#", "2"),
),
},
data.ImportStep(),
},
})
}

func testCheckAzureRMDnsAaaaRecordExists(resourceName string) resource.TestCheckFunc {
return func(s *terraform.State) error {
conn := acceptance.AzureProvider.Meta().(*clients.Client).Dns.RecordSetsClient
Expand Down Expand Up @@ -483,3 +510,25 @@ resource "azurerm_dns_aaaa_record" "test" {
}
`, data.RandomInteger, data.Locations.Primary, data.RandomInteger, data.RandomInteger)
}

func testAccAzureRMDnsAAAARecord_uncompressed(data acceptance.TestData) string {
return fmt.Sprintf(`
resource "azurerm_resource_group" "test" {
name = "acctestRG-%d"
location = "%s"
}

resource "azurerm_dns_zone" "test" {
name = "acctestzone%d.com"
resource_group_name = "${azurerm_resource_group.test.name}"
}

resource "azurerm_dns_aaaa_record" "test" {
name = "myarecord%d"
resource_group_name = "${azurerm_resource_group.test.name}"
zone_name = "${azurerm_dns_zone.test.name}"
ttl = 300
records = ["2607:f8b0:4005:0800:0000:0000:0000:1003", "2201:1234:1234::1"]
}
`, data.RandomInteger, data.Locations.Primary, data.RandomInteger, data.RandomInteger)
}