From c33810f5cee2a54956d98c1153f0dbae6b6ed30f Mon Sep 17 00:00:00 2001 From: Jay Wang Date: Fri, 14 Apr 2017 15:19:22 -0700 Subject: [PATCH 1/5] Updated test to include the scenario --- .../azurerm/resource_arm_subnet_test.go | 21 +++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/builtin/providers/azurerm/resource_arm_subnet_test.go b/builtin/providers/azurerm/resource_arm_subnet_test.go index 5f1f2bcbe4..264b0a5403 100644 --- a/builtin/providers/azurerm/resource_arm_subnet_test.go +++ b/builtin/providers/azurerm/resource_arm_subnet_test.go @@ -13,7 +13,7 @@ import ( func TestAccAzureRMSubnet_basic(t *testing.T) { ri := acctest.RandInt() - config := fmt.Sprintf(testAccAzureRMSubnet_basic, ri, ri, ri) + config := fmt.Sprintf(testAccAzureRMSubnet_basic, ri, ri, ri, ri, ri) resource.Test(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, @@ -33,7 +33,7 @@ func TestAccAzureRMSubnet_basic(t *testing.T) { func TestAccAzureRMSubnet_disappears(t *testing.T) { ri := acctest.RandInt() - config := fmt.Sprintf(testAccAzureRMSubnet_basic, ri, ri, ri) + config := fmt.Sprintf(testAccAzureRMSubnet_basic, ri, ri, ri, ri, ri) resource.Test(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, @@ -152,5 +152,22 @@ resource "azurerm_subnet" "test" { resource_group_name = "${azurerm_resource_group.test.name}" virtual_network_name = "${azurerm_virtual_network.test.name}" address_prefix = "10.0.2.0/24" + route_table_id = "${azurerm_route_table.test.id}" +} + +resource "azurerm_route_table" "test" { + name = "acctestroutetable%d" + resource_group_name = "${azurerm_resource_group.test.name}" + location = "West US" +} + +resource "azurerm_route" "test" { + name = "acctestroute%d" + resource_group_name = "${azurerm_resource_group.test.name}" + route_table_name = "${azurerm_route_table.test.name}" + + address_prefix = "10.100.0.0/14" + next_hop_type = "VirtualAppliance" + next_hop_in_ip_address = "10.10.1.1" } ` From 279b00dd12cafc4b54dc6612373312bc449678a9 Mon Sep 17 00:00:00 2001 From: Jay Wang Date: Fri, 14 Apr 2017 16:50:46 -0700 Subject: [PATCH 2/5] Lock Route Table / Subnets --- .../providers/azurerm/resource_arm_subnet.go | 21 +++++++++++++++++++ builtin/providers/azurerm/resourceid.go | 10 +++++++++ 2 files changed, 31 insertions(+) diff --git a/builtin/providers/azurerm/resource_arm_subnet.go b/builtin/providers/azurerm/resource_arm_subnet.go index c5329b9f86..769e7ebd8e 100644 --- a/builtin/providers/azurerm/resource_arm_subnet.go +++ b/builtin/providers/azurerm/resource_arm_subnet.go @@ -96,6 +96,15 @@ func resourceArmSubnetCreate(d *schema.ResourceData, meta interface{}) error { properties.RouteTable = &network.RouteTable{ ID: &rtId, } + + routeTableName, err := parseRouteTableName(rtId) + + if err != nil { + return err + } + + armMutexKV.Lock(routeTableName) + defer armMutexKV.Unlock(routeTableName) } subnet := network.Subnet{ @@ -182,6 +191,18 @@ func resourceArmSubnetDelete(d *schema.ResourceData, meta interface{}) error { name := id.Path["subnets"] vnetName := id.Path["virtualNetworks"] + if v, ok := d.GetOk("route_table_id"); ok { + rtId := v.(string) + routeTableName, err := parseRouteTableName(rtId) + + if err != nil { + return err + } + + armMutexKV.Lock(routeTableName) + defer armMutexKV.Unlock(routeTableName) + } + armMutexKV.Lock(vnetName) defer armMutexKV.Unlock(vnetName) diff --git a/builtin/providers/azurerm/resourceid.go b/builtin/providers/azurerm/resourceid.go index b05f4d75f7..af0f35091c 100644 --- a/builtin/providers/azurerm/resourceid.go +++ b/builtin/providers/azurerm/resourceid.go @@ -95,3 +95,13 @@ func parseAzureResourceID(id string) (*ResourceID, error) { return idObj, nil } + +func parseRouteTableName(routeTableId string) (string, error) { + id, err := parseAzureResourceID(routeTableId) + + if err != nil { + return "", fmt.Errorf("[ERROR] Unable to parse Route Table ID '%s': %+v", routeTableId, err) + } + + return id.Path["routeTables"], nil +} From f712880fee355a69567b40cda2486c198da15aec Mon Sep 17 00:00:00 2001 From: Jay Wang Date: Fri, 14 Apr 2017 15:19:22 -0700 Subject: [PATCH 3/5] Lock Route Table / Subnets --- .../providers/azurerm/resource_arm_subnet.go | 19 +++++++++++++++++ .../azurerm/resource_arm_subnet_test.go | 21 +++++++++++++++++-- builtin/providers/azurerm/resourceid.go | 9 ++++++++ 3 files changed, 47 insertions(+), 2 deletions(-) diff --git a/builtin/providers/azurerm/resource_arm_subnet.go b/builtin/providers/azurerm/resource_arm_subnet.go index 65df4f447c..f91dd85b4d 100644 --- a/builtin/providers/azurerm/resource_arm_subnet.go +++ b/builtin/providers/azurerm/resource_arm_subnet.go @@ -104,6 +104,14 @@ func resourceArmSubnetCreate(d *schema.ResourceData, meta interface{}) error { properties.RouteTable = &network.RouteTable{ ID: &rtId, } + + routeTableName, err := parseRouteTableName(rtId) + if err != nil { + return err + } + + armMutexKV.Lock(routeTableName) + defer armMutexKV.Unlock(routeTableName) } subnet := network.Subnet{ @@ -201,6 +209,17 @@ func resourceArmSubnetDelete(d *schema.ResourceData, meta interface{}) error { defer armMutexKV.Unlock(networkSecurityGroupName) } + if v, ok := d.GetOk("route_table_id"); ok { + rtId := v.(string) + routeTableName, err := parseRouteTableName(rtId) + if err != nil { + return err + } + + armMutexKV.Lock(routeTableName) + defer armMutexKV.Unlock(routeTableName) + } + armMutexKV.Lock(vnetName) defer armMutexKV.Unlock(vnetName) diff --git a/builtin/providers/azurerm/resource_arm_subnet_test.go b/builtin/providers/azurerm/resource_arm_subnet_test.go index 5f1f2bcbe4..264b0a5403 100644 --- a/builtin/providers/azurerm/resource_arm_subnet_test.go +++ b/builtin/providers/azurerm/resource_arm_subnet_test.go @@ -13,7 +13,7 @@ import ( func TestAccAzureRMSubnet_basic(t *testing.T) { ri := acctest.RandInt() - config := fmt.Sprintf(testAccAzureRMSubnet_basic, ri, ri, ri) + config := fmt.Sprintf(testAccAzureRMSubnet_basic, ri, ri, ri, ri, ri) resource.Test(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, @@ -33,7 +33,7 @@ func TestAccAzureRMSubnet_basic(t *testing.T) { func TestAccAzureRMSubnet_disappears(t *testing.T) { ri := acctest.RandInt() - config := fmt.Sprintf(testAccAzureRMSubnet_basic, ri, ri, ri) + config := fmt.Sprintf(testAccAzureRMSubnet_basic, ri, ri, ri, ri, ri) resource.Test(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, @@ -152,5 +152,22 @@ resource "azurerm_subnet" "test" { resource_group_name = "${azurerm_resource_group.test.name}" virtual_network_name = "${azurerm_virtual_network.test.name}" address_prefix = "10.0.2.0/24" + route_table_id = "${azurerm_route_table.test.id}" +} + +resource "azurerm_route_table" "test" { + name = "acctestroutetable%d" + resource_group_name = "${azurerm_resource_group.test.name}" + location = "West US" +} + +resource "azurerm_route" "test" { + name = "acctestroute%d" + resource_group_name = "${azurerm_resource_group.test.name}" + route_table_name = "${azurerm_route_table.test.name}" + + address_prefix = "10.100.0.0/14" + next_hop_type = "VirtualAppliance" + next_hop_in_ip_address = "10.10.1.1" } ` diff --git a/builtin/providers/azurerm/resourceid.go b/builtin/providers/azurerm/resourceid.go index f981b410b8..281bd8f9b0 100644 --- a/builtin/providers/azurerm/resourceid.go +++ b/builtin/providers/azurerm/resourceid.go @@ -104,3 +104,12 @@ func parseNetworkSecurityGroupName(networkSecurityGroupId string) (string, error return id.Path["networkSecurityGroups"], nil } + +func parseRouteTableName(routeTableId string) (string, error) { + id, err := parseAzureResourceID(routeTableId) + if err != nil { + return "", fmt.Errorf("[ERROR] Unable to parse Route Table ID '%s': %+v", routeTableId, err) + } + + return id.Path["routeTables"], nil +} From c42b2381c6d7add222362964da187a9f78a65c90 Mon Sep 17 00:00:00 2001 From: Jay Wang Date: Tue, 18 Apr 2017 17:17:14 -0700 Subject: [PATCH 4/5] Added check for empty strings in resource id parsing logic. --- builtin/providers/azurerm/resourceid.go | 5 +++++ builtin/providers/azurerm/resourceid_test.go | 12 ++++++++++++ 2 files changed, 17 insertions(+) diff --git a/builtin/providers/azurerm/resourceid.go b/builtin/providers/azurerm/resourceid.go index 281bd8f9b0..4f89945e79 100644 --- a/builtin/providers/azurerm/resourceid.go +++ b/builtin/providers/azurerm/resourceid.go @@ -53,6 +53,11 @@ func parseAzureResourceID(id string) (*ResourceID, error) { key := components[current] value := components[current+1] + // Check key/value for empty strings. + if key == "" || value == "" { + return nil, fmt.Errorf("Key/Value cannot be empty strings. Key: '%s', Value: '%s'", key, value) + } + // Catch the subscriptionID before it can be overwritten by another "subscriptions" // value in the ID which is the case for the Service Bus subscription resource if key == "subscriptions" && subscriptionID == "" { diff --git a/builtin/providers/azurerm/resourceid_test.go b/builtin/providers/azurerm/resourceid_test.go index dff6ed8004..4359b70d19 100644 --- a/builtin/providers/azurerm/resourceid_test.go +++ b/builtin/providers/azurerm/resourceid_test.go @@ -11,6 +11,18 @@ func TestParseAzureResourceID(t *testing.T) { expectedResourceID *ResourceID expectError bool }{ + { + // Missing "resourceGroups". + "/subscriptions/00000000-0000-0000-0000-000000000000//myResourceGroup/", + nil, + true, + }, + { + // Empty resource group ID. + "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups//", + nil, + true, + }, { "random", nil, From 8706d2181f695ea919904291d0ac2c4c1788e417 Mon Sep 17 00:00:00 2001 From: tombuildsstuff Date: Thu, 20 Apr 2017 12:19:35 +0100 Subject: [PATCH 5/5] Fixing the import test by adding missing formatting values --- builtin/providers/azurerm/import_arm_subnet_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/builtin/providers/azurerm/import_arm_subnet_test.go b/builtin/providers/azurerm/import_arm_subnet_test.go index 90cf28fe51..8384d8b3f9 100644 --- a/builtin/providers/azurerm/import_arm_subnet_test.go +++ b/builtin/providers/azurerm/import_arm_subnet_test.go @@ -12,7 +12,7 @@ func TestAccAzureRMSubnet_importBasic(t *testing.T) { resourceName := "azurerm_subnet.test" ri := acctest.RandInt() - config := fmt.Sprintf(testAccAzureRMSubnet_basic, ri, ri, ri) + config := fmt.Sprintf(testAccAzureRMSubnet_basic, ri, ri, ri, ri, ri) resource.Test(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) },