Skip to content

Commit

Permalink
Merge pull request #781 from svanharmelen/f-augmented-nsg
Browse files Browse the repository at this point in the history
`azurerm_network_security_group` - support for augmented security rules
  • Loading branch information
tombuildsstuff authored Mar 1, 2018
2 parents f89a4b4 + e10e4ad commit 0db754b
Show file tree
Hide file tree
Showing 6 changed files with 245 additions and 130 deletions.
20 changes: 0 additions & 20 deletions azurerm/network_security_rule.go

This file was deleted.

43 changes: 0 additions & 43 deletions azurerm/network_security_rule_test.go

This file was deleted.

234 changes: 179 additions & 55 deletions azurerm/resource_arm_network_security_group.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"fmt"

"github.com/Azure/azure-sdk-for-go/services/network/mgmt/2017-09-01/network"
multierror "github.com/hashicorp/go-multierror"
"github.com/hashicorp/terraform/helper/schema"
"github.com/hashicorp/terraform/helper/validation"
"github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils"
Expand Down Expand Up @@ -33,7 +34,7 @@ func resourceArmNetworkSecurityGroup() *schema.Resource {
"resource_group_name": resourceGroupNameSchema(),

"security_rule": {
Type: schema.TypeList,
Type: schema.TypeSet,
Optional: true,
Computed: true,
Elem: &schema.Resource{
Expand All @@ -50,30 +51,62 @@ func resourceArmNetworkSecurityGroup() *schema.Resource {
},

"protocol": {
Type: schema.TypeString,
Required: true,
ValidateFunc: validateNetworkSecurityRuleProtocol,
StateFunc: ignoreCaseStateFunc,
Type: schema.TypeString,
Required: true,
ValidateFunc: validation.StringInSlice([]string{
string(network.SecurityRuleProtocolAsterisk),
string(network.SecurityRuleProtocolTCP),
string(network.SecurityRuleProtocolUDP),
}, true),
DiffSuppressFunc: ignoreCaseDiffSuppressFunc,
},

"source_port_range": {
Type: schema.TypeString,
Required: true,
Optional: true,
},

"source_port_ranges": {
Type: schema.TypeSet,
Optional: true,
Elem: &schema.Schema{Type: schema.TypeString},
Set: schema.HashString,
},

"destination_port_range": {
Type: schema.TypeString,
Required: true,
Optional: true,
},

"destination_port_ranges": {
Type: schema.TypeSet,
Optional: true,
Elem: &schema.Schema{Type: schema.TypeString},
Set: schema.HashString,
},

"source_address_prefix": {
Type: schema.TypeString,
Required: true,
Optional: true,
},

"source_address_prefixes": {
Type: schema.TypeSet,
Optional: true,
Elem: &schema.Schema{Type: schema.TypeString},
Set: schema.HashString,
},

"destination_address_prefix": {
Type: schema.TypeString,
Required: true,
Optional: true,
},

"destination_address_prefixes": {
Type: schema.TypeSet,
Optional: true,
Elem: &schema.Schema{Type: schema.TypeString},
Set: schema.HashString,
},

"access": {
Expand Down Expand Up @@ -216,83 +249,174 @@ func resourceArmNetworkSecurityGroupDelete(d *schema.ResourceData, meta interfac
return err
}

func flattenNetworkSecurityRules(rules *[]network.SecurityRule) []interface{} {
result := make([]interface{}, 0)
func expandAzureRmSecurityRules(d *schema.ResourceData) ([]network.SecurityRule, error) {
sgRules := d.Get("security_rule").(*schema.Set)
rules := make([]network.SecurityRule, 0)

for _, sgRaw := range sgRules.List() {
sgRule := sgRaw.(map[string]interface{})

if err := validateSecurityRule(sgRule); err != nil {
return nil, err
}

name := sgRule["name"].(string)
source_port_range := sgRule["source_port_range"].(string)
destination_port_range := sgRule["destination_port_range"].(string)
source_address_prefix := sgRule["source_address_prefix"].(string)
destination_address_prefix := sgRule["destination_address_prefix"].(string)
priority := int32(sgRule["priority"].(int))
access := sgRule["access"].(string)
direction := sgRule["direction"].(string)
protocol := sgRule["protocol"].(string)

properties := network.SecurityRulePropertiesFormat{
SourcePortRange: &source_port_range,
DestinationPortRange: &destination_port_range,
SourceAddressPrefix: &source_address_prefix,
DestinationAddressPrefix: &destination_address_prefix,
Priority: &priority,
Access: network.SecurityRuleAccess(access),
Direction: network.SecurityRuleDirection(direction),
Protocol: network.SecurityRuleProtocol(protocol),
}

if v := sgRule["description"].(string); v != "" {
properties.Description = &v
}

if r, ok := sgRule["source_port_ranges"].(*schema.Set); ok && r.Len() > 0 {
var sourcePortRanges []string
for _, v := range r.List() {
s := v.(string)
sourcePortRanges = append(sourcePortRanges, s)
}
properties.SourcePortRanges = &sourcePortRanges
}

if r, ok := sgRule["destination_port_ranges"].(*schema.Set); ok && r.Len() > 0 {
var destinationPortRanges []string
for _, v := range r.List() {
s := v.(string)
destinationPortRanges = append(destinationPortRanges, s)
}
properties.DestinationPortRanges = &destinationPortRanges
}

if r, ok := sgRule["source_address_prefixes"].(*schema.Set); ok && r.Len() > 0 {
var sourceAddressPrefixes []string
for _, v := range r.List() {
s := v.(string)
sourceAddressPrefixes = append(sourceAddressPrefixes, s)
}
properties.SourceAddressPrefixes = &sourceAddressPrefixes
}

if r, ok := sgRule["destination_address_prefixes"].(*schema.Set); ok && r.Len() > 0 {
var destinationAddressPrefixes []string
for _, v := range r.List() {
s := v.(string)
destinationAddressPrefixes = append(destinationAddressPrefixes, s)
}
properties.DestinationAddressPrefixes = &destinationAddressPrefixes
}

rules = append(rules, network.SecurityRule{
Name: &name,
SecurityRulePropertiesFormat: &properties,
})
}

return rules, nil
}

func flattenNetworkSecurityRules(rules *[]network.SecurityRule) *schema.Set {
result := resourceArmNetworkSecurityGroup().Schema["security_rule"].ZeroValue().(*schema.Set)

if rules != nil {
for _, rule := range *rules {
sgRule := make(map[string]interface{})
sgRule["name"] = *rule.Name

if props := rule.SecurityRulePropertiesFormat; props != nil {
if props.Description != nil {
sgRule["description"] = *props.Description
}

if props.DestinationAddressPrefix != nil {
sgRule["destination_address_prefix"] = *props.DestinationAddressPrefix
}
if props.DestinationAddressPrefixes != nil {
sgRule["destination_address_prefixes"] = sliceToSet(*props.DestinationAddressPrefixes)
}
if props.DestinationPortRange != nil {
sgRule["destination_port_range"] = *props.DestinationPortRange
}
if props.DestinationPortRanges != nil {
sgRule["destination_port_ranges"] = sliceToSet(*props.DestinationPortRanges)
}
if props.SourceAddressPrefix != nil {
sgRule["source_address_prefix"] = *props.SourceAddressPrefix
}
if props.SourceAddressPrefixes != nil {
sgRule["source_address_prefixes"] = sliceToSet(*props.SourceAddressPrefixes)
}
if props.SourcePortRange != nil {
sgRule["source_port_range"] = *props.SourcePortRange
}
if props.SourcePortRanges != nil {
sgRule["source_port_ranges"] = sliceToSet(*props.SourcePortRanges)
}

sgRule["protocol"] = string(props.Protocol)
sgRule["priority"] = int(*props.Priority)
sgRule["access"] = string(props.Access)
sgRule["direction"] = string(props.Direction)
sgRule["protocol"] = string(props.Protocol)

if props.Description != nil {
sgRule["description"] = *props.Description
}
}

result = append(result, sgRule)
result.Add(sgRule)
}
}

return result
}

func expandAzureRmSecurityRules(d *schema.ResourceData) ([]network.SecurityRule, error) {
sgRules := d.Get("security_rule").([]interface{})
rules := make([]network.SecurityRule, 0)

for _, sgRaw := range sgRules {
data := sgRaw.(map[string]interface{})

name := data["name"].(string)
source_port_range := data["source_port_range"].(string)
destination_port_range := data["destination_port_range"].(string)
source_address_prefix := data["source_address_prefix"].(string)
destination_address_prefix := data["destination_address_prefix"].(string)
priority := int32(data["priority"].(int))
access := data["access"].(string)
direction := data["direction"].(string)
protocol := data["protocol"].(string)

properties := network.SecurityRulePropertiesFormat{
SourcePortRange: &source_port_range,
DestinationPortRange: &destination_port_range,
SourceAddressPrefix: &source_address_prefix,
DestinationAddressPrefix: &destination_address_prefix,
Priority: &priority,
Access: network.SecurityRuleAccess(access),
Direction: network.SecurityRuleDirection(direction),
Protocol: network.SecurityRuleProtocol(protocol),
}

if v := data["description"].(string); v != "" {
properties.Description = &v
}

rule := network.SecurityRule{
Name: &name,
SecurityRulePropertiesFormat: &properties,
}
func sliceToSet(slice []string) *schema.Set {
set := &schema.Set{F: schema.HashString}
for _, v := range slice {
set.Add(v)
}
return set
}

rules = append(rules, rule)
func validateSecurityRule(sgRule map[string]interface{}) error {
var err *multierror.Error

sourcePortRange := sgRule["source_port_range"].(string)
sourcePortRanges := sgRule["source_port_ranges"].(*schema.Set)
destinationPortRange := sgRule["destination_port_range"].(string)
destinationPortRanges := sgRule["destination_port_ranges"].(*schema.Set)
sourceAddressPrefix := sgRule["source_address_prefix"].(string)
sourceAddressPrefixes := sgRule["source_address_prefixes"].(*schema.Set)
destinationAddressPrefix := sgRule["destination_address_prefix"].(string)
destinationAddressPrefixes := sgRule["destination_address_prefixes"].(*schema.Set)

if sourcePortRange != "" && sourcePortRanges.Len() > 0 {
err = multierror.Append(err, fmt.Errorf(
"only one of \"source_port_range\" and \"source_port_ranges\" can be used per security rule"))
}
if destinationPortRange != "" && destinationPortRanges.Len() > 0 {
err = multierror.Append(err, fmt.Errorf(
"only one of \"destination_port_range\" and \"destination_port_ranges\" can be used per security rule"))
}
if sourceAddressPrefix != "" && sourceAddressPrefixes.Len() > 0 {
err = multierror.Append(err, fmt.Errorf(
"only one of \"source_address_prefix\" and \"source_address_prefixes\" can be used per security rule"))
}
if destinationAddressPrefix != "" && destinationAddressPrefixes.Len() > 0 {
err = multierror.Append(err, fmt.Errorf(
"only one of \"destination_address_prefix\" and \"destination_address_prefixes\" can be used per security rule"))
}

return rules, nil
return err.ErrorOrNil()
}
Loading

0 comments on commit 0db754b

Please sign in to comment.