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

Add Network Rule Set to Servicebus Namespace #5533

Expand Up @@ -74,6 +74,74 @@ func resourceArmServiceBusNamespace() *schema.Resource {
DiffSuppressFunc: suppress.CaseDifference,
},

"network_rulesets": {
Type: schema.TypeList,
Optional: true,
MaxItems: 1,
Computed: true,
ConfigMode: schema.SchemaConfigModeAttr,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{

"default_action": {
Type: schema.TypeString,
Required: true,
ValidateFunc: validation.StringInSlice([]string{
string(servicebus.Allow),
string(servicebus.Deny),
}, false),
},

"virtual_network_rule": {
Type: schema.TypeList,
Optional: true,
ConfigMode: schema.SchemaConfigModeAttr,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{

// the API returns the subnet ID's resource group name in lowercase
// https://github.com/Azure/azure-sdk-for-go/issues/5855
"subnet_id": {
Type: schema.TypeString,
Required: true,
ValidateFunc: azure.ValidateResourceID,
DiffSuppressFunc: suppress.CaseDifference,
},

"ignore_missing_virtual_network_service_endpoint": {
Type: schema.TypeBool,
Optional: true,
},
},
},
},

"ip_rule": {
Type: schema.TypeList,
Optional: true,
ConfigMode: schema.SchemaConfigModeAttr,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"ip_mask": {
Type: schema.TypeString,
Required: true,
},

"action": {
Type: schema.TypeString,
Optional: true,
Default: string(servicebus.NetworkRuleIPActionAllow),
ValidateFunc: validation.StringInSlice([]string{
string(servicebus.NetworkRuleIPActionAllow),
}, false),
},
},
},
},
},
},
},

"capacity": {
Type: schema.TypeInt,
Optional: true,
Expand Down Expand Up @@ -188,6 +256,27 @@ func resourceArmServiceBusNamespaceCreateUpdate(d *schema.ResourceData, meta int

d.SetId(*read.ID)

ruleSets, hasRuleSets := d.GetOk("network_rulesets")
if hasRuleSets {
rulesets := servicebus.NetworkRuleSet{
NetworkRuleSetProperties: expandServiceBusNetworkRuleset(ruleSets.([]interface{})),
}

// cannot use network rulesets with the basic SKU
if parameters.Sku.Name != servicebus.Basic && parameters.Sku.Name != servicebus.Standard {
if _, err := client.CreateOrUpdateNetworkRuleSet(ctx, resourceGroup, name, rulesets); err != nil {
return fmt.Errorf("Error setting network ruleset properties for Service Bus %q (resource group %q): %v", name, resourceGroup, err)
}
} else {
// so if the user has specified the non default rule sets throw a validation error
if rulesets.DefaultAction != servicebus.Deny ||
(rulesets.IPRules != nil && len(*rulesets.IPRules) > 0) ||
(rulesets.VirtualNetworkRules != nil && len(*rulesets.VirtualNetworkRules) > 0) {
return fmt.Errorf("network_rulesets cannot be used when the SKU is basic or Standard")
}
}
}

return resourceArmServiceBusNamespaceRead(d, meta)
}

Expand Down Expand Up @@ -228,6 +317,15 @@ func resourceArmServiceBusNamespaceRead(d *schema.ResourceData, meta interface{}
d.Set("zone_redundant", properties.ZoneRedundant)
}

ruleset, err := client.GetNetworkRuleSet(ctx, resourceGroup, name)
if err != nil {
return fmt.Errorf("Error making Read request on Service Bus %q Network Ruleset: %+v", name, err)
}

if err := d.Set("network_rulesets", flattenServiceBusNetworkRuleset(ruleset)); err != nil {
return fmt.Errorf("Error setting `network_ruleset` for Service Bus %s: %v", name, err)
}

keys, err := clientStable.ListKeys(ctx, resourceGroup, name, serviceBusNamespaceDefaultAuthorizationRule)
if err != nil {
log.Printf("[WARN] Unable to List default keys for Namespace %q (Resource Group %q): %+v", name, resourceGroup, err)
Expand Down Expand Up @@ -268,3 +366,94 @@ func resourceArmServiceBusNamespaceDelete(d *schema.ResourceData, meta interface

return nil
}

func expandServiceBusNetworkRuleset(input []interface{}) *servicebus.NetworkRuleSetProperties {
if len(input) == 0 {
return nil
}

block := input[0].(map[string]interface{})

ruleset := servicebus.NetworkRuleSetProperties{
DefaultAction: servicebus.DefaultAction(block["default_action"].(string)),
}

if v, ok := block["virtual_network_rule"].([]interface{}); ok {
if len(v) > 0 {
var rules []servicebus.NWRuleSetVirtualNetworkRules
for _, r := range v {
rblock := r.(map[string]interface{})
rules = append(rules, servicebus.NWRuleSetVirtualNetworkRules{
Subnet: &servicebus.Subnet{
ID: utils.String(rblock["subnet_id"].(string)),
},
IgnoreMissingVnetServiceEndpoint: utils.Bool(rblock["ignore_missing_virtual_network_service_endpoint"].(bool)),
})
}

ruleset.VirtualNetworkRules = &rules
}
}

if v, ok := block["ip_rule"].([]interface{}); ok {
if len(v) > 0 {
var rules []servicebus.NWRuleSetIPRules
for _, r := range v {
rblock := r.(map[string]interface{})
rules = append(rules, servicebus.NWRuleSetIPRules{
IPMask: utils.String(rblock["ip_mask"].(string)),
Action: servicebus.NetworkRuleIPAction(rblock["action"].(string)),
})
}

ruleset.IPRules = &rules
}
}

return &ruleset
}

func flattenServiceBusNetworkRuleset(ruleset servicebus.NetworkRuleSet) []interface{} {
if ruleset.NetworkRuleSetProperties == nil {
return nil
}

vnetBlocks := make([]interface{}, 0)
if vnetRules := ruleset.NetworkRuleSetProperties.VirtualNetworkRules; vnetRules != nil {
for _, vnetRule := range *vnetRules {
block := make(map[string]interface{})

if s := vnetRule.Subnet; s != nil {
if v := s.ID; v != nil {
block["subnet_id"] = *v
}
}

if v := vnetRule.IgnoreMissingVnetServiceEndpoint; v != nil {
block["ignore_missing_virtual_network_service_endpoint"] = *v
}

vnetBlocks = append(vnetBlocks, block)
}
}
ipBlocks := make([]interface{}, 0)
if ipRules := ruleset.NetworkRuleSetProperties.IPRules; ipRules != nil {
for _, ipRule := range *ipRules {
block := make(map[string]interface{})

block["action"] = string(ipRule.Action)

if v := ipRule.IPMask; v != nil {
block["ip_mask"] = *v
}

ipBlocks = append(ipBlocks, block)
}
}

return []interface{}{map[string]interface{}{
"default_action": string(ruleset.DefaultAction),
"virtual_network_rule": vnetBlocks,
"ip_rule": ipBlocks,
}}
}