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

Event Grid support for inbound ip filter #9922

Merged
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
95 changes: 95 additions & 0 deletions azurerm/internal/services/eventgrid/eventgrid.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
package eventgrid

import (
"github.com/Azure/azure-sdk-for-go/services/preview/eventgrid/mgmt/2020-04-01-preview/eventgrid"
"github.com/hashicorp/terraform-plugin-sdk/helper/schema"
"github.com/hashicorp/terraform-plugin-sdk/helper/validation"
"github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils"
)

func eventSubscriptionPublicNetworkAccessEnabled() *schema.Schema {
return &schema.Schema{
Type: schema.TypeBool,
Optional: true,
Default: true,
}
}

func eventSubscriptionInboundIPRule() *schema.Schema {
return &schema.Schema{
Type: schema.TypeList,
Optional: true,
MaxItems: 128,
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(eventgrid.Allow),
ValidateFunc: validation.StringInSlice([]string{
string(eventgrid.Allow),
}, false),
},
},
},
}
}

func expandPublicNetworkAccess(d *schema.ResourceData) eventgrid.PublicNetworkAccess {
if v, ok := d.GetOk("public_network_access_enabled"); ok {
enabled := eventgrid.Disabled
if v.(bool) {
enabled = eventgrid.Enabled
}
return enabled
}
return eventgrid.Disabled
}

func expandInboundIPRules(d *schema.ResourceData) *[]eventgrid.InboundIPRule {
inboundIPRuleList := d.Get("inbound_ip_rule").([]interface{})
if len(inboundIPRuleList) == 0 {
return nil
}

rules := make([]eventgrid.InboundIPRule, 0)

for _, r := range inboundIPRuleList {
rawRule := r.(map[string]interface{})
rule := &eventgrid.InboundIPRule{
Action: eventgrid.IPActionType(rawRule["action"].(string)),
IPMask: utils.String(rawRule["ip_mask"].(string)),
}

rules = append(rules, *rule)
}
return &rules
}

func flattenPublicNetworkAccess(in eventgrid.PublicNetworkAccess) bool {
return in == eventgrid.Enabled
}

func flattenInboundIPRules(in *[]eventgrid.InboundIPRule) []interface{} {
rules := make([]interface{}, 0)
if in == nil {
return rules
}

for _, r := range *in {
rawRule := make(map[string]interface{})

rawRule["action"] = string(r.Action)

if r.IPMask != nil {
rawRule["ip_mask"] = *r.IPMask
}
rules = append(rules, rawRule)
}
return rules
}
46 changes: 31 additions & 15 deletions azurerm/internal/services/eventgrid/eventgrid_domain_resource.go
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,10 @@ func resourceEventGridDomain() *schema.Resource {
},
},

"public_network_access_enabled": eventSubscriptionPublicNetworkAccessEnabled(),

"inbound_ip_rule": eventSubscriptionInboundIPRule(),

"endpoint": {
Type: schema.TypeString,
Computed: true,
Expand Down Expand Up @@ -170,7 +174,7 @@ func resourceEventGridDomainCreateUpdate(d *schema.ResourceData, meta interface{
existing, err := client.Get(ctx, resourceGroup, name)
if err != nil {
if !utils.ResponseWasNotFound(existing.Response) {
return fmt.Errorf("Error checking for presence of existing EventGrid Domain %q (Resource Group %q): %s", name, resourceGroup, err)
return fmt.Errorf("checking for presence of existing EventGrid Domain %q (Resource Group %q): %s", name, resourceGroup, err)
}
}

Expand All @@ -183,8 +187,10 @@ func resourceEventGridDomainCreateUpdate(d *schema.ResourceData, meta interface{
t := d.Get("tags").(map[string]interface{})

domainProperties := &eventgrid.DomainProperties{
InputSchemaMapping: expandAzureRmEventgridDomainInputMapping(d),
InputSchema: eventgrid.InputSchema(d.Get("input_schema").(string)),
InputSchemaMapping: expandAzureRmEventgridDomainInputMapping(d),
InputSchema: eventgrid.InputSchema(d.Get("input_schema").(string)),
PublicNetworkAccess: expandPublicNetworkAccess(d),
InboundIPRules: expandInboundIPRules(d),
}

domain := eventgrid.Domain{
Expand All @@ -197,19 +203,19 @@ func resourceEventGridDomainCreateUpdate(d *schema.ResourceData, meta interface{

future, err := client.CreateOrUpdate(ctx, resourceGroup, name, domain)
if err != nil {
return fmt.Errorf("Error creating/updating EventGrid Domain %q (Resource Group %q): %s", name, resourceGroup, err)
return fmt.Errorf("creating/updating EventGrid Domain %q (Resource Group %q): %s", name, resourceGroup, err)
}

if err = future.WaitForCompletionRef(ctx, client.Client); err != nil {
return fmt.Errorf("Error waiting for EventGrid Domain %q (Resource Group %q) to become available: %s", name, resourceGroup, err)
return fmt.Errorf("waiting for EventGrid Domain %q (Resource Group %q) to become available: %s", name, resourceGroup, err)
}

read, err := client.Get(ctx, resourceGroup, name)
if err != nil {
return fmt.Errorf("Error retrieving EventGrid Domain %q (Resource Group %q): %s", name, resourceGroup, err)
return fmt.Errorf("retrieving EventGrid Domain %q (Resource Group %q): %s", name, resourceGroup, err)
}
if read.ID == nil {
return fmt.Errorf("Cannot read EventGrid Domain %q (resource group %s) ID", name, resourceGroup)
return fmt.Errorf("reading EventGrid Domain %q (resource group %s) ID", name, resourceGroup)
}

d.SetId(*read.ID)
Expand All @@ -235,7 +241,7 @@ func resourceEventGridDomainRead(d *schema.ResourceData, meta interface{}) error
return nil
}

return fmt.Errorf("Error making Read request on EventGrid Domain %q: %+v", id.Name, err)
return fmt.Errorf("making Read request on EventGrid Domain %q: %+v", id.Name, err)
}

d.Set("name", resp.Name)
Expand All @@ -251,24 +257,34 @@ func resourceEventGridDomainRead(d *schema.ResourceData, meta interface{}) error

inputMappingFields, err := flattenAzureRmEventgridDomainInputMapping(props.InputSchemaMapping)
if err != nil {
return fmt.Errorf("Unable to flatten `input_schema_mapping_fields` for EventGrid Domain %q (Resource Group %q): %s", id.Name, id.ResourceGroup, err)
return fmt.Errorf("flattening `input_schema_mapping_fields` for EventGrid Domain %q (Resource Group %q): %s", id.Name, id.ResourceGroup, err)
}
if err := d.Set("input_mapping_fields", inputMappingFields); err != nil {
return fmt.Errorf("Error setting `input_schema_mapping_fields` for EventGrid Domain %q (Resource Group %q): %s", id.Name, id.ResourceGroup, err)
return fmt.Errorf("setting `input_schema_mapping_fields` for EventGrid Domain %q (Resource Group %q): %s", id.Name, id.ResourceGroup, err)
}

inputMappingDefaultValues, err := flattenAzureRmEventgridDomainInputMappingDefaultValues(props.InputSchemaMapping)
if err != nil {
return fmt.Errorf("Unable to flatten `input_schema_mapping_default_values` for EventGrid Domain %q (Resource Group %q): %s", id.Name, id.ResourceGroup, err)
return fmt.Errorf("flattening `input_schema_mapping_default_values` for EventGrid Domain %q (Resource Group %q): %s", id.Name, id.ResourceGroup, err)
}
if err := d.Set("input_mapping_default_values", inputMappingDefaultValues); err != nil {
return fmt.Errorf("Error setting `input_schema_mapping_fields` for EventGrid Domain %q (Resource Group %q): %s", id.Name, id.ResourceGroup, err)
return fmt.Errorf("setting `input_schema_mapping_fields` for EventGrid Domain %q (Resource Group %q): %s", id.Name, id.ResourceGroup, err)
}

publicNetworkAccessEnabled := flattenPublicNetworkAccess(props.PublicNetworkAccess)
if err := d.Set("public_network_access_enabled", publicNetworkAccessEnabled); err != nil {
return fmt.Errorf("setting `public_network_access_enabled` in EventGrid Domain %q (Resource Group %q): %+v", id.Name, id.ResourceGroup, err)
}

inboundIPRules := flattenInboundIPRules(props.InboundIPRules)
if err := d.Set("inbound_ip_rule", inboundIPRules); err != nil {
return fmt.Errorf("setting `inbound_ip_rule` in EventGrid Domain %q (Resource Group %q): %+v", id.Name, id.ResourceGroup, err)
}
}

keys, err := client.ListSharedAccessKeys(ctx, id.ResourceGroup, id.Name)
if err != nil {
return fmt.Errorf("Error retrieving Shared Access Keys for EventGrid Domain %q: %+v", id.Name, err)
return fmt.Errorf("retrieving Shared Access Keys for EventGrid Domain %q: %+v", id.Name, err)
}
d.Set("primary_access_key", keys.Key1)
d.Set("secondary_access_key", keys.Key2)
Expand All @@ -291,14 +307,14 @@ func resourceEventGridDomainDelete(d *schema.ResourceData, meta interface{}) err
if response.WasNotFound(future.Response()) {
return nil
}
return fmt.Errorf("Error deleting Event Grid Domain %q: %+v", id.Name, err)
return fmt.Errorf("deleting Event Grid Domain %q: %+v", id.Name, err)
}

if err = future.WaitForCompletionRef(ctx, client.Client); err != nil {
if response.WasNotFound(future.Response()) {
return nil
}
return fmt.Errorf("Error deleting Event Grid Domain %q: %+v", id.Name, err)
return fmt.Errorf("deleting Event Grid Domain %q: %+v", id.Name, err)
}

return nil
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,26 @@ func TestAccEventGridDomain_basicWithTags(t *testing.T) {
})
}

func TestAccEventGridDomain_inboundIPRules(t *testing.T) {
data := acceptance.BuildTestData(t, "azurerm_eventgrid_domain", "test")
r := EventGridDomainResource{}

data.ResourceTest(t, r, []resource.TestStep{
{
Config: r.inboundIPRules(data),
Check: resource.ComposeTestCheckFunc(
check.That(data.ResourceName).ExistsInAzure(r),
check.That(data.ResourceName).Key("inbound_ip_rule.#").HasValue("2"),
check.That(data.ResourceName).Key("inbound_ip_rule.0.ip_mask").HasValue("10.0.0.0/16"),
check.That(data.ResourceName).Key("inbound_ip_rule.1.ip_mask").HasValue("10.1.0.0/16"),
check.That(data.ResourceName).Key("inbound_ip_rule.0.action").HasValue("Allow"),
check.That(data.ResourceName).Key("inbound_ip_rule.1.action").HasValue("Allow"),
),
},
data.ImportStep(),
})
}

func (EventGridDomainResource) Exists(ctx context.Context, clients *clients.Client, state *terraform.InstanceState) (*bool, error) {
id, err := parse.DomainID(state.ID)
if err != nil {
Expand Down Expand Up @@ -188,3 +208,34 @@ resource "azurerm_eventgrid_domain" "test" {
}
`, data.RandomInteger, data.Locations.Primary, data.RandomInteger)
}

func (EventGridDomainResource) inboundIPRules(data acceptance.TestData) string {
return fmt.Sprintf(`
provider "azurerm" {
features {}
}

resource "azurerm_resource_group" "test" {
name = "acctestRG-%d"
location = "%s"
}

resource "azurerm_eventgrid_domain" "test" {
name = "acctesteg-%d"
location = azurerm_resource_group.test.location
resource_group_name = azurerm_resource_group.test.name

public_network_access_enabled = true

inbound_ip_rule {
ip_mask = "10.0.0.0/16"
action = "Allow"
}

inbound_ip_rule {
ip_mask = "10.1.0.0/16"
action = "Allow"
}
}
`, data.RandomInteger, data.Locations.Primary, data.RandomInteger)
}
36 changes: 26 additions & 10 deletions azurerm/internal/services/eventgrid/eventgrid_topic_resource.go
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,10 @@ func resourceEventGridTopic() *schema.Resource {
},
},

"public_network_access_enabled": eventSubscriptionPublicNetworkAccessEnabled(),

"inbound_ip_rule": eventSubscriptionInboundIPRule(),

"endpoint": {
Type: schema.TypeString,
Computed: true,
Expand Down Expand Up @@ -170,7 +174,7 @@ func resourceEventGridTopicCreateUpdate(d *schema.ResourceData, meta interface{}
existing, err := client.Get(ctx, resourceGroup, name)
if err != nil {
if !utils.ResponseWasNotFound(existing.Response) {
return fmt.Errorf("Error checking for presence of existing EventGrid Topic %q (Resource Group %q): %s", name, resourceGroup, err)
return fmt.Errorf("checking for presence of existing EventGrid Topic %q (Resource Group %q): %s", name, resourceGroup, err)
}
}

Expand All @@ -183,8 +187,10 @@ func resourceEventGridTopicCreateUpdate(d *schema.ResourceData, meta interface{}
t := d.Get("tags").(map[string]interface{})

topicProperties := &eventgrid.TopicProperties{
InputSchemaMapping: expandAzureRmEventgridTopicInputMapping(d),
InputSchema: eventgrid.InputSchema(d.Get("input_schema").(string)),
InputSchemaMapping: expandAzureRmEventgridTopicInputMapping(d),
InputSchema: eventgrid.InputSchema(d.Get("input_schema").(string)),
PublicNetworkAccess: expandPublicNetworkAccess(d),
InboundIPRules: expandInboundIPRules(d),
}

properties := eventgrid.Topic{
Expand All @@ -209,7 +215,7 @@ func resourceEventGridTopicCreateUpdate(d *schema.ResourceData, meta interface{}
return err
}
if read.ID == nil {
return fmt.Errorf("Cannot read EventGrid Topic %s (resource group %s) ID", name, resourceGroup)
return fmt.Errorf("reading EventGrid Topic %s (resource group %s) ID", name, resourceGroup)
}

d.SetId(*read.ID)
Expand All @@ -235,7 +241,7 @@ func resourceEventGridTopicRead(d *schema.ResourceData, meta interface{}) error
return nil
}

return fmt.Errorf("Error making Read request on EventGrid Topic '%s': %+v", id.Name, err)
return fmt.Errorf("making Read request on EventGrid Topic '%s': %+v", id.Name, err)
}
if props := resp.TopicProperties; props != nil {
d.Set("endpoint", props.Endpoint)
Expand All @@ -247,21 +253,31 @@ func resourceEventGridTopicRead(d *schema.ResourceData, meta interface{}) error
return fmt.Errorf("Unable to flatten `input_schema_mapping_fields` for EventGrid Topic %q (Resource Group %q): %s", id.Name, id.ResourceGroup, err)
}
if err := d.Set("input_mapping_fields", inputMappingFields); err != nil {
return fmt.Errorf("Error setting `input_schema_mapping_fields` for EventGrid Topic %q (Resource Group %q): %s", id.Name, id.ResourceGroup, err)
return fmt.Errorf("setting `input_schema_mapping_fields` for EventGrid Topic %q (Resource Group %q): %s", id.Name, id.ResourceGroup, err)
}

inputMappingDefaultValues, err := flattenAzureRmEventgridTopicInputMappingDefaultValues(props.InputSchemaMapping)
if err != nil {
return fmt.Errorf("Unable to flatten `input_schema_mapping_default_values` for EventGrid Topic %q (Resource Group %q): %s", id.Name, id.ResourceGroup, err)
}
if err := d.Set("input_mapping_default_values", inputMappingDefaultValues); err != nil {
return fmt.Errorf("Error setting `input_schema_mapping_fields` for EventGrid Topic %q (Resource Group %q): %s", id.Name, id.ResourceGroup, err)
return fmt.Errorf("setting `input_schema_mapping_fields` for EventGrid Topic %q (Resource Group %q): %s", id.Name, id.ResourceGroup, err)
}

publicNetworkAccessEnabled := flattenPublicNetworkAccess(props.PublicNetworkAccess)
if err := d.Set("public_network_access_enabled", publicNetworkAccessEnabled); err != nil {
return fmt.Errorf("setting `public_network_access_enabled` in EventGrid Topic %q (Resource Group %q): %+v", id.Name, id.ResourceGroup, err)
}

inboundIPRules := flattenInboundIPRules(props.InboundIPRules)
if err := d.Set("inbound_ip_rule", inboundIPRules); err != nil {
return fmt.Errorf("setting `inbound_ip_rule` in EventGrid Topic %q (Resource Group %q): %+v", id.Name, id.ResourceGroup, err)
}
}

keys, err := client.ListSharedAccessKeys(ctx, id.ResourceGroup, id.Name)
if err != nil {
return fmt.Errorf("Error retrieving Shared Access Keys for EventGrid Topic '%s': %+v", id.Name, err)
return fmt.Errorf("retrieving Shared Access Keys for EventGrid Topic '%s': %+v", id.Name, err)
}

d.Set("name", resp.Name)
Expand Down Expand Up @@ -295,14 +311,14 @@ func resourceEventGridTopicDelete(d *schema.ResourceData, meta interface{}) erro
if response.WasNotFound(future.Response()) {
return nil
}
return fmt.Errorf("Error deleting EventGrid Topic %q: %+v", id.Name, err)
return fmt.Errorf("deleting EventGrid Topic %q: %+v", id.Name, err)
}

if err = future.WaitForCompletionRef(ctx, client.Client); err != nil {
if response.WasNotFound(future.Response()) {
return nil
}
return fmt.Errorf("Error deleting EventGrid Topic %q: %+v", id.Name, err)
return fmt.Errorf("deleting EventGrid Topic %q: %+v", id.Name, err)
}

return nil
Expand Down
Loading