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

provider/azurerm: Locking around Network Security Group / Subnets #13637

Merged
merged 5 commits into from
Apr 18, 2017
Merged
Show file tree
Hide file tree
Changes from all 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
19 changes: 19 additions & 0 deletions builtin/providers/azurerm/resource_arm_network_interface_card.go
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,14 @@ func resourceArmNetworkInterfaceCreate(d *schema.ResourceData, meta interface{})
properties.NetworkSecurityGroup = &network.SecurityGroup{
ID: &nsgId,
}

networkSecurityGroupName, err := parseNetworkSecurityGroupName(nsgId)
if err != nil {
return err
}

armMutexKV.Lock(networkSecurityGroupName)
defer armMutexKV.Unlock(networkSecurityGroupName)
}

dns, hasDns := d.GetOk("dns_servers")
Expand Down Expand Up @@ -308,6 +316,17 @@ func resourceArmNetworkInterfaceDelete(d *schema.ResourceData, meta interface{})
resGroup := id.ResourceGroup
name := id.Path["networkInterfaces"]

if v, ok := d.GetOk("network_security_group_id"); ok {
networkSecurityGroupId := v.(string)
networkSecurityGroupName, err := parseNetworkSecurityGroupName(networkSecurityGroupId)
if err != nil {
return err
}

armMutexKV.Lock(networkSecurityGroupName)
defer armMutexKV.Unlock(networkSecurityGroupName)
}

_, err = ifaceClient.Delete(resGroup, name, make(chan struct{}))

return err
Expand Down
19 changes: 19 additions & 0 deletions builtin/providers/azurerm/resource_arm_subnet.go
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,14 @@ func resourceArmSubnetCreate(d *schema.ResourceData, meta interface{}) error {
properties.NetworkSecurityGroup = &network.SecurityGroup{
ID: &nsgId,
}

networkSecurityGroupName, err := parseNetworkSecurityGroupName(nsgId)
if err != nil {
return err
}

armMutexKV.Lock(networkSecurityGroupName)
defer armMutexKV.Unlock(networkSecurityGroupName)
}

if v, ok := d.GetOk("route_table_id"); ok {
Expand Down Expand Up @@ -182,6 +190,17 @@ func resourceArmSubnetDelete(d *schema.ResourceData, meta interface{}) error {
name := id.Path["subnets"]
vnetName := id.Path["virtualNetworks"]

if v, ok := d.GetOk("network_security_group_id"); ok {
networkSecurityGroupId := v.(string)
networkSecurityGroupName, err := parseNetworkSecurityGroupName(networkSecurityGroupId)
if err != nil {
return err
}

armMutexKV.Lock(networkSecurityGroupName)
defer armMutexKV.Unlock(networkSecurityGroupName)
}

armMutexKV.Lock(vnetName)
defer armMutexKV.Unlock(vnetName)

Expand Down
60 changes: 60 additions & 0 deletions builtin/providers/azurerm/resource_arm_virtual_network.go
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,21 @@ func resourceArmVirtualNetworkCreate(d *schema.ResourceData, meta interface{}) e
Tags: expandTags(tags),
}

networkSecurityGroupNames := make([]string, 0)
for _, subnet := range *vnet.VirtualNetworkPropertiesFormat.Subnets {
if subnet.NetworkSecurityGroup != nil {
nsgName, err := parseNetworkSecurityGroupName(*subnet.NetworkSecurityGroup.ID)
if err != nil {
return err
}

networkSecurityGroupNames = append(networkSecurityGroupNames, nsgName)
}
}

azureRMVirtualNetworkLockNetworkSecurityGroups(&networkSecurityGroupNames)
defer azureRMVirtualNetworkUnlockNetworkSecurityGroups(&networkSecurityGroupNames)

_, err := vnetClient.CreateOrUpdate(resGroup, name, vnet, make(chan struct{}))
if err != nil {
return err
Expand Down Expand Up @@ -182,6 +197,14 @@ func resourceArmVirtualNetworkDelete(d *schema.ResourceData, meta interface{}) e
resGroup := id.ResourceGroup
name := id.Path["virtualNetworks"]

nsgNames, err := expandAzureRmVirtualNetworkVirtualNetworkSecurityGroupNames(d)
if err != nil {
return fmt.Errorf("[ERROR] Error parsing Network Security Group ID's: %+v", err)
}

azureRMVirtualNetworkLockNetworkSecurityGroups(&nsgNames)
defer azureRMVirtualNetworkUnlockNetworkSecurityGroups(&nsgNames)

_, err = vnetClient.Delete(resGroup, name, make(chan struct{}))

return err
Expand Down Expand Up @@ -245,3 +268,40 @@ func resourceAzureSubnetHash(v interface{}) int {
}
return hashcode.String(subnet)
}

func expandAzureRmVirtualNetworkVirtualNetworkSecurityGroupNames(d *schema.ResourceData) ([]string, error) {
nsgNames := make([]string, 0)

if v, ok := d.GetOk("subnet"); ok {
subnets := v.(*schema.Set).List()
for _, subnet := range subnets {
subnet, ok := subnet.(map[string]interface{})
if !ok {
return nil, fmt.Errorf("[ERROR] Subnet should be a Hash - was '%+v'", subnet)
}

networkSecurityGroupId := subnet["security_group"].(string)
if networkSecurityGroupId != "" {
nsgName, err := parseNetworkSecurityGroupName(networkSecurityGroupId)
if err != nil {
return nil, err
}

nsgNames = append(nsgNames, nsgName)
}
}
}

return nsgNames, nil
}

func azureRMVirtualNetworkUnlockNetworkSecurityGroups(networkSecurityGroupNames *[]string) {
for _, networkSecurityGroupName := range *networkSecurityGroupNames {
armMutexKV.Unlock(networkSecurityGroupName)
}
}
func azureRMVirtualNetworkLockNetworkSecurityGroups(networkSecurityGroupNames *[]string) {
for _, networkSecurityGroupName := range *networkSecurityGroupNames {
armMutexKV.Lock(networkSecurityGroupName)
}
}
9 changes: 9 additions & 0 deletions builtin/providers/azurerm/resourceid.go
Original file line number Diff line number Diff line change
Expand Up @@ -95,3 +95,12 @@ func parseAzureResourceID(id string) (*ResourceID, error) {

return idObj, nil
}

func parseNetworkSecurityGroupName(networkSecurityGroupId string) (string, error) {
id, err := parseAzureResourceID(networkSecurityGroupId)
if err != nil {
return "", fmt.Errorf("[ERROR] Unable to Parse Network Security Group ID '%s': %+v", networkSecurityGroupId, err)
}

return id.Path["networkSecurityGroups"], nil
}