Skip to content

Commit

Permalink
Feature: Add 'ip_version' to Public IP Address (#2019)
Browse files Browse the repository at this point in the history
* Feature: Add 'ip_version' to Public IP Address

* Public IP Data Source Info for 'ip_version'

* Public IP Documentation

Update to include 'ip_version' for data and resource documentation.

* Making the IP Version field case sensitive

* Fixing the broken tests

* Adding back in the Zones test

```
$ acctests azurerm TestAccAzureRMPublicIpStatic_zones
=== RUN   TestAccAzureRMPublicIpStatic_zones
--- PASS: TestAccAzureRMPublicIpStatic_zones (111.60s)
PASS
ok  	github.com/terraform-providers/terraform-provider-azurerm/azurerm	113.048s
```
  • Loading branch information
Krueladin authored and tombuildsstuff committed Oct 13, 2018
1 parent 43e9c50 commit 5862ac5
Show file tree
Hide file tree
Showing 8 changed files with 294 additions and 3 deletions.
9 changes: 9 additions & 0 deletions azurerm/data_source_public_ip.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,11 @@ func dataSourceArmPublicIP() *schema.Resource {

"resource_group_name": resourceGroupNameForDataSourceSchema(),

"ip_version": {
Type: schema.TypeString,
Computed: true,
},

"domain_name_label": {
Type: schema.TypeString,
Computed: true,
Expand Down Expand Up @@ -73,6 +78,10 @@ func dataSourceArmPublicIPRead(d *schema.ResourceData, meta interface{}) error {
}
}

if ipVersion := props.PublicIPAddressVersion; string(ipVersion) != "" {
d.Set("ip_version", string(ipVersion))
}

if v := props.IPAddress; v != nil && *v != "" {
d.Set("ip_address", v)
}
Expand Down
1 change: 1 addition & 0 deletions azurerm/data_source_public_ip_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ func TestAccDataSourceAzureRMPublicIP_basic(t *testing.T) {
resource.TestCheckResourceAttr(dataSourceName, "idle_timeout_in_minutes", "30"),
resource.TestCheckResourceAttrSet(dataSourceName, "fqdn"),
resource.TestCheckResourceAttrSet(dataSourceName, "ip_address"),
resource.TestCheckResourceAttr(dataSourceName, "ip_version", "IPv4"),
resource.TestCheckResourceAttr(dataSourceName, "tags.%", "1"),
resource.TestCheckResourceAttr(dataSourceName, "tags.environment", "test"),
),
Expand Down
26 changes: 25 additions & 1 deletion azurerm/helpers/validate/network.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,30 @@ import (
"net"
)

func IPv6Address(i interface{}, k string) (_ []string, errors []error) {
return validateIpv6Address(i, k, false)
}

func validateIpv6Address(i interface{}, k string, allowEmpty bool) (_ []string, errors []error) {
v, ok := i.(string)
if !ok {
errors = append(errors, fmt.Errorf("expected type of %q to be string", k))
return
}

if v == "" && allowEmpty {
return
}

ip := net.ParseIP(v)
if six := ip.To16(); six == nil {
errors = append(errors, fmt.Errorf("%q is not a valid IPv6 address: %q", k, v))
}

return

}

func IPv4Address(i interface{}, k string) (_ []string, errors []error) {
return validateIpv4Address(i, k, false)
}
Expand All @@ -26,7 +50,7 @@ func validateIpv4Address(i interface{}, k string, allowEmpty bool) (_ []string,

ip := net.ParseIP(v)
if four := ip.To4(); four == nil {
errors = append(errors, fmt.Errorf("%q is not a valid IP4 address: %q", k, v))
errors = append(errors, fmt.Errorf("%q is not a valid IPv4 address: %q", k, v))
}

return
Expand Down
51 changes: 51 additions & 0 deletions azurerm/helpers/validate/network_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,57 @@ import (
"testing"
)

func TestIPv6Address(t *testing.T) {
cases := []struct {
IP string
Errors int
}{
{
IP: "",
Errors: 1,
},
{
IP: "0.0.0.0",
Errors: 0,
},
{
IP: "not:a:real:address:1:2:3:4",
Errors: 1,
},
{
IP: "text",
Errors: 1,
},
{
IP: "::",
Errors: 0,
},
{
IP: "0:0:0:0:0:0:0:0",
Errors: 0,
},
{
IP: "2001:0db8:85a3:0:0:8a2e:0370:7334",
Errors: 0,
},
{
IP: "2001:0db8:85a3:0000:0000:8a2e:0370:7334",
Errors: 0,
},
}

for _, tc := range cases {
t.Run(tc.IP, func(t *testing.T) {
_, errors := IPv6Address(tc.IP, "test")

if len(errors) != tc.Errors {
t.Fatalf("Expected IPv6Address to return %d error(s) not %d", tc.Errors, len(errors))
}
})
}

}

func TestIPv4Address(t *testing.T) {
cases := []struct {
IP string
Expand Down
24 changes: 23 additions & 1 deletion azurerm/resource_arm_public_ip.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,12 @@ package azurerm

import (
"fmt"
"github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/suppress"
"log"
"regexp"
"strings"

"github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/suppress"

"github.com/Azure/azure-sdk-for-go/services/network/mgmt/2018-04-01/network"
"github.com/hashicorp/terraform/helper/schema"
"github.com/hashicorp/terraform/helper/validation"
Expand Down Expand Up @@ -60,6 +61,18 @@ func resourceArmPublicIp() *schema.Resource {
}, true),
},

"ip_version": {
Type: schema.TypeString,
Optional: true,
Default: string(network.IPv4),
ForceNew: true,
DiffSuppressFunc: suppress.CaseDifference,
ValidateFunc: validation.StringInSlice([]string{
string(network.IPv4),
string(network.IPv6),
}, true),
},

"sku": {
Type: schema.TypeString,
Optional: true,
Expand Down Expand Up @@ -122,6 +135,13 @@ func resourceArmPublicIpCreate(d *schema.ResourceData, meta interface{}) error {

idleTimeout := d.Get("idle_timeout_in_minutes").(int)
ipAllocationMethod := network.IPAllocationMethod(d.Get("public_ip_address_allocation").(string))
ipVersion := network.IPVersion(d.Get("ip_version").(string))

if strings.EqualFold(string(ipVersion), string(network.IPv6)) {
if strings.EqualFold(string(ipAllocationMethod), "static") {
return fmt.Errorf("Cannot specify publicIpAllocationMethod as Static for IPv6 PublicIp")
}
}

if strings.ToLower(string(sku.Name)) == "standard" {
if strings.ToLower(string(ipAllocationMethod)) != "static" {
Expand All @@ -135,6 +155,7 @@ func resourceArmPublicIpCreate(d *schema.ResourceData, meta interface{}) error {
Sku: &sku,
PublicIPAddressPropertiesFormat: &network.PublicIPAddressPropertiesFormat{
PublicIPAllocationMethod: ipAllocationMethod,
PublicIPAddressVersion: ipVersion,
IdleTimeoutInMinutes: utils.Int32(int32(idleTimeout)),
},
Tags: expandTags(tags),
Expand Down Expand Up @@ -218,6 +239,7 @@ func resourceArmPublicIpRead(d *schema.ResourceData, meta interface{}) error {

if props := resp.PublicIPAddressPropertiesFormat; props != nil {
d.Set("public_ip_address_allocation", strings.ToLower(string(props.PublicIPAllocationMethod)))
d.Set("ip_version", strings.ToLower(string(props.PublicIPAddressVersion)))

if settings := props.DNSSettings; settings != nil {
d.Set("fqdn", settings.Fqdn)
Expand Down
Loading

0 comments on commit 5862ac5

Please sign in to comment.