Skip to content

Commit

Permalink
Implement private_ip_address_version for network interfaces.
Browse files Browse the repository at this point in the history
  • Loading branch information
literatesnow committed Dec 19, 2018
1 parent b44b8b7 commit 5b634bd
Show file tree
Hide file tree
Showing 3 changed files with 134 additions and 28 deletions.
88 changes: 61 additions & 27 deletions azurerm/resource_arm_network_interface.go
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ func resourceArmNetworkInterface() *schema.Resource {

"subnet_id": {
Type: schema.TypeString,
Required: true,
Optional: true,
DiffSuppressFunc: suppress.CaseDifference,
ValidateFunc: azure.ValidateResourceID,
},
Expand All @@ -81,6 +81,17 @@ func resourceArmNetworkInterface() *schema.Resource {
Optional: true,
},

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

"private_ip_address_allocation": {
Type: schema.TypeString,
Required: true,
Expand Down Expand Up @@ -360,12 +371,16 @@ func resourceArmNetworkInterfaceRead(d *schema.ResourceData, meta interface{}) e
if configs[0].InterfaceIPConfigurationPropertiesFormat != nil {
privateIPAddress := configs[0].InterfaceIPConfigurationPropertiesFormat.PrivateIPAddress
d.Set("private_ip_address", *privateIPAddress)
privateIPAddressVersion := configs[0].InterfaceIPConfigurationPropertiesFormat.PrivateIPAddressVersion
d.Set("private_ip_address_version", string(privateIPAddressVersion))
}

addresses := make([]interface{}, 0)
for _, config := range configs {
if config.InterfaceIPConfigurationPropertiesFormat != nil {
addresses = append(addresses, *config.InterfaceIPConfigurationPropertiesFormat.PrivateIPAddress)
if config.InterfaceIPConfigurationPropertiesFormat.PrivateIPAddressVersion == network.IPv4 {
addresses = append(addresses, *config.InterfaceIPConfigurationPropertiesFormat.PrivateIPAddress)
}
}
}

Expand Down Expand Up @@ -456,18 +471,20 @@ func resourceArmNetworkInterfaceDelete(d *schema.ResourceData, meta interface{})
data := configRaw.(map[string]interface{})

subnet_id := data["subnet_id"].(string)
subnetId, err2 := parseAzureResourceID(subnet_id)
if err2 != nil {
return err2
}
subnetName := subnetId.Path["subnets"]
if !sliceContainsValue(subnetNamesToLock, subnetName) {
subnetNamesToLock = append(subnetNamesToLock, subnetName)
}
if subnet_id != "" {
subnetId, err2 := parseAzureResourceID(subnet_id)
if err2 != nil {
return err2
}
subnetName := subnetId.Path["subnets"]
if !sliceContainsValue(subnetNamesToLock, subnetName) {
subnetNamesToLock = append(subnetNamesToLock, subnetName)
}

virtualNetworkName := subnetId.Path["virtualNetworks"]
if !sliceContainsValue(virtualNetworkNamesToLock, virtualNetworkName) {
virtualNetworkNamesToLock = append(virtualNetworkNamesToLock, virtualNetworkName)
virtualNetworkName := subnetId.Path["virtualNetworks"]
if !sliceContainsValue(virtualNetworkNamesToLock, virtualNetworkName) {
virtualNetworkNamesToLock = append(virtualNetworkNamesToLock, virtualNetworkName)
}
}
}

Expand Down Expand Up @@ -497,13 +514,21 @@ func flattenNetworkInterfaceIPConfigurations(ipConfigs *[]network.InterfaceIPCon
props := ipConfig.InterfaceIPConfigurationPropertiesFormat

niIPConfig["name"] = *ipConfig.Name
niIPConfig["subnet_id"] = *props.Subnet.ID

if props.Subnet != nil {
niIPConfig["subnet_id"] = *props.Subnet.ID
}

niIPConfig["private_ip_address_allocation"] = strings.ToLower(string(props.PrivateIPAllocationMethod))

if props.PrivateIPAllocationMethod == network.Static {
niIPConfig["private_ip_address"] = *props.PrivateIPAddress
}

if props.PrivateIPAddressVersion != "" {
niIPConfig["private_ip_address_version"] = props.PrivateIPAddressVersion
}

if props.PublicIPAddress != nil {
niIPConfig["public_ip_address_id"] = *props.PublicIPAddress.ID
}
Expand Down Expand Up @@ -560,29 +585,38 @@ func expandAzureRmNetworkInterfaceIpConfigurations(d *schema.ResourceData) ([]ne

subnet_id := data["subnet_id"].(string)
private_ip_allocation_method := data["private_ip_address_allocation"].(string)
private_ip_address_version := network.IPVersion(data["private_ip_address_version"].(string))

allocationMethod := network.IPAllocationMethod(private_ip_allocation_method)
properties := network.InterfaceIPConfigurationPropertiesFormat{
Subnet: &network.Subnet{
ID: &subnet_id,
},
PrivateIPAllocationMethod: allocationMethod,
PrivateIPAddressVersion: private_ip_address_version,
}

subnetId, err := parseAzureResourceID(subnet_id)
if err != nil {
return []network.InterfaceIPConfiguration{}, nil, nil, err
if private_ip_address_version == network.IPv4 && subnet_id == "" {
return nil, nil, nil, fmt.Errorf("Required field `ip_configuration`, `subnet_id` must be specified when using IPv4.")
}

subnetName := subnetId.Path["subnets"]
virtualNetworkName := subnetId.Path["virtualNetworks"]
if subnet_id != "" {
properties.Subnet = &network.Subnet{
ID: &subnet_id,
}

if !sliceContainsValue(subnetNamesToLock, subnetName) {
subnetNamesToLock = append(subnetNamesToLock, subnetName)
}
subnetId, err := parseAzureResourceID(subnet_id)
if err != nil {
return []network.InterfaceIPConfiguration{}, nil, nil, err
}

subnetName := subnetId.Path["subnets"]
virtualNetworkName := subnetId.Path["virtualNetworks"]

if !sliceContainsValue(virtualNetworkNamesToLock, virtualNetworkName) {
virtualNetworkNamesToLock = append(virtualNetworkNamesToLock, virtualNetworkName)
if !sliceContainsValue(subnetNamesToLock, subnetName) {
subnetNamesToLock = append(subnetNamesToLock, subnetName)
}

if !sliceContainsValue(virtualNetworkNamesToLock, virtualNetworkName) {
virtualNetworkNamesToLock = append(virtualNetworkNamesToLock, virtualNetworkName)
}
}

if v := data["private_ip_address"].(string); v != "" {
Expand Down
70 changes: 70 additions & 0 deletions azurerm/resource_arm_network_interface_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -366,6 +366,26 @@ func TestAccAzureRMNetworkInterface_IPAddressesBug1286(t *testing.T) {
})
}

func TestAccAzureRMNetworkInterface_IPAddressesFeature2543(t *testing.T) {
resourceName := "azurerm_network_interface.test"
rInt := acctest.RandInt()
resource.ParallelTest(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
CheckDestroy: testCheckAzureRMNetworkInterfaceDestroy,
Steps: []resource.TestStep{
{
Config: testAccAzureRMNetworkInterface_withIPv6Addresses(rInt, testLocation()),
Check: resource.ComposeTestCheckFunc(
testCheckAzureRMNetworkInterfaceExists(resourceName),
resource.TestCheckResourceAttr(resourceName, "ip_configuration.0.private_ip_address_version", "IPv4"),
resource.TestCheckResourceAttr(resourceName, "ip_configuration.1.private_ip_address_version", "IPv6"),
),
},
},
})
}

func TestAccAzureRMNetworkInterface_bug7986(t *testing.T) {
rInt := acctest.RandInt()
resource.ParallelTest(t, resource.TestCase{
Expand Down Expand Up @@ -912,6 +932,56 @@ resource "azurerm_network_interface" "test" {
`, rInt, location, rInt, rInt, rInt)
}

func testAccAzureRMNetworkInterface_withIPv6Addresses(rInt int, location string) string {
return fmt.Sprintf(`
resource "azurerm_resource_group" "test" {
name = "acctest-rg-%d"
location = "%s"
}
resource "azurerm_virtual_network" "test" {
name = "acctestvn-%d"
address_space = ["10.0.0.0/16"]
location = "${azurerm_resource_group.test.location}"
resource_group_name = "${azurerm_resource_group.test.name}"
}
resource "azurerm_subnet" "test" {
name = "testsubnet"
resource_group_name = "${azurerm_resource_group.test.name}"
virtual_network_name = "${azurerm_virtual_network.test.name}"
address_prefix = "10.0.2.0/24"
}
resource "azurerm_public_ip" "test" {
name = "test-%d"
location = "${azurerm_resource_group.test.location}"
resource_group_name = "${azurerm_resource_group.test.name}"
public_ip_address_allocation = "static"
domain_name_label = "${azurerm_resource_group.test.name}"
}
resource "azurerm_network_interface" "test" {
name = "acctestni-%d"
location = "${azurerm_resource_group.test.location}"
resource_group_name = "${azurerm_resource_group.test.name}"
ip_configuration {
name = "testconfiguration1"
subnet_id = "${azurerm_subnet.test.id}"
private_ip_address_allocation = "dynamic"
primary = true
}
ip_configuration {
name = "testconfiguration2"
private_ip_address_version = "IPv6"
private_ip_address_allocation = "dynamic"
}
}
`, rInt, location, rInt, rInt, rInt)
}

func testAccAzureRMNetworkInterface_multipleLoadBalancers(rInt int, location string) string {
return fmt.Sprintf(`
resource "azurerm_resource_group" "test" {
Expand Down
4 changes: 3 additions & 1 deletion website/docs/r/network_interface.html.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -80,12 +80,14 @@ The `ip_configuration` block supports:

* `name` - (Required) User-defined name of the IP.

* `subnet_id` - (Required) Reference to a subnet in which this NIC has been created.
* `subnet_id` - (Optional) Reference to a subnet in which this NIC has been created. Required when `private_ip_address_version` is IPv4.

* `private_ip_address` - (Optional) Static IP Address.

* `private_ip_address_allocation` - (Required) Defines how a private IP address is assigned. Options are Static or Dynamic.

* `private_ip_address_version` - (Optional) The IP Version to use, IPv6 or IPv4. Defaults to IPv4.

* `public_ip_address_id` - (Optional) Reference to a Public IP Address to associate with this NIC

* `application_gateway_backend_address_pools_ids` - (Optional / **Deprecated**) List of Application Gateway Backend Address Pool IDs references to which this NIC belongs
Expand Down

0 comments on commit 5b634bd

Please sign in to comment.