Skip to content

Commit

Permalink
new data source: azurerm_sentinel_alert_rule_template (#7020)
Browse files Browse the repository at this point in the history
This PR implement the alert rule template required in #6448.
  • Loading branch information
magodo committed Jan 14, 2021
1 parent 7a46303 commit 2e7f23c
Show file tree
Hide file tree
Showing 13 changed files with 836 additions and 6 deletions.
9 changes: 7 additions & 2 deletions azurerm/internal/services/sentinel/client/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,19 @@ import (
)

type Client struct {
AlertRulesClient *securityinsight.AlertRulesClient
AlertRulesClient *securityinsight.AlertRulesClient
AlertRuleTemplatesClient *securityinsight.AlertRuleTemplatesClient
}

func NewClient(o *common.ClientOptions) *Client {
alertRulesClient := securityinsight.NewAlertRulesClientWithBaseURI(o.ResourceManagerEndpoint, o.SubscriptionId)
o.ConfigureClient(&alertRulesClient.Client, o.ResourceManagerAuthorizer)

alertRuleTemplatesClient := securityinsight.NewAlertRuleTemplatesClientWithBaseURI(o.ResourceManagerEndpoint, o.SubscriptionId)
o.ConfigureClient(&alertRuleTemplatesClient.Client, o.ResourceManagerAuthorizer)

return &Client{
AlertRulesClient: &alertRulesClient,
AlertRulesClient: &alertRulesClient,
AlertRuleTemplatesClient: &alertRuleTemplatesClient,
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
package parse

// NOTE: this file is generated via 'go:generate' - manual changes will be overwritten

import (
"fmt"
"strings"

"github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure"
)

type SentinelAlertRuleTemplateId struct {
SubscriptionId string
ResourceGroup string
WorkspaceName string
AlertRuleTemplateName string
}

func NewSentinelAlertRuleTemplateID(subscriptionId, resourceGroup, workspaceName, alertRuleTemplateName string) SentinelAlertRuleTemplateId {
return SentinelAlertRuleTemplateId{
SubscriptionId: subscriptionId,
ResourceGroup: resourceGroup,
WorkspaceName: workspaceName,
AlertRuleTemplateName: alertRuleTemplateName,
}
}

func (id SentinelAlertRuleTemplateId) String() string {
segments := []string{
fmt.Sprintf("Alert Rule Template Name %q", id.AlertRuleTemplateName),
fmt.Sprintf("Workspace Name %q", id.WorkspaceName),
fmt.Sprintf("Resource Group %q", id.ResourceGroup),
}
segmentsStr := strings.Join(segments, " / ")
return fmt.Sprintf("%s: (%s)", "Sentinel Alert Rule Template", segmentsStr)
}

func (id SentinelAlertRuleTemplateId) ID() string {
fmtString := "/subscriptions/%s/resourceGroups/%s/providers/Microsoft.OperationalInsights/workspaces/%s/providers/Microsoft.SecurityInsights/AlertRuleTemplates/%s"
return fmt.Sprintf(fmtString, id.SubscriptionId, id.ResourceGroup, id.WorkspaceName, id.AlertRuleTemplateName)
}

// SentinelAlertRuleTemplateID parses a SentinelAlertRuleTemplate ID into an SentinelAlertRuleTemplateId struct
func SentinelAlertRuleTemplateID(input string) (*SentinelAlertRuleTemplateId, error) {
id, err := azure.ParseAzureResourceID(input)
if err != nil {
return nil, err
}

resourceId := SentinelAlertRuleTemplateId{
SubscriptionId: id.SubscriptionID,
ResourceGroup: id.ResourceGroup,
}

if resourceId.SubscriptionId == "" {
return nil, fmt.Errorf("ID was missing the 'subscriptions' element")
}

if resourceId.ResourceGroup == "" {
return nil, fmt.Errorf("ID was missing the 'resourceGroups' element")
}

if resourceId.WorkspaceName, err = id.PopSegment("workspaces"); err != nil {
return nil, err
}
if resourceId.AlertRuleTemplateName, err = id.PopSegment("AlertRuleTemplates"); err != nil {
return nil, err
}

if err := id.ValidateNoEmptySegments(input); err != nil {
return nil, err
}

return &resourceId, nil
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
package parse

// NOTE: this file is generated via 'go:generate' - manual changes will be overwritten

import (
"testing"

"github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/resourceid"
)

var _ resourceid.Formatter = SentinelAlertRuleTemplateId{}

func TestSentinelAlertRuleTemplateIDFormatter(t *testing.T) {
actual := NewSentinelAlertRuleTemplateID("12345678-1234-9876-4563-123456789012", "resGroup1", "workspace1", "template1").ID()
expected := "/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/resGroup1/providers/Microsoft.OperationalInsights/workspaces/workspace1/providers/Microsoft.SecurityInsights/AlertRuleTemplates/template1"
if actual != expected {
t.Fatalf("Expected %q but got %q", expected, actual)
}
}

func TestSentinelAlertRuleTemplateID(t *testing.T) {
testData := []struct {
Input string
Error bool
Expected *SentinelAlertRuleTemplateId
}{

{
// empty
Input: "",
Error: true,
},

{
// missing SubscriptionId
Input: "/",
Error: true,
},

{
// missing value for SubscriptionId
Input: "/subscriptions/",
Error: true,
},

{
// missing ResourceGroup
Input: "/subscriptions/12345678-1234-9876-4563-123456789012/",
Error: true,
},

{
// missing value for ResourceGroup
Input: "/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/",
Error: true,
},

{
// missing WorkspaceName
Input: "/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/resGroup1/providers/Microsoft.OperationalInsights/",
Error: true,
},

{
// missing value for WorkspaceName
Input: "/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/resGroup1/providers/Microsoft.OperationalInsights/workspaces/",
Error: true,
},

{
// missing AlertRuleTemplateName
Input: "/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/resGroup1/providers/Microsoft.OperationalInsights/workspaces/workspace1/providers/Microsoft.SecurityInsights/",
Error: true,
},

{
// missing value for AlertRuleTemplateName
Input: "/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/resGroup1/providers/Microsoft.OperationalInsights/workspaces/workspace1/providers/Microsoft.SecurityInsights/AlertRuleTemplates/",
Error: true,
},

{
// valid
Input: "/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/resGroup1/providers/Microsoft.OperationalInsights/workspaces/workspace1/providers/Microsoft.SecurityInsights/AlertRuleTemplates/template1",
Expected: &SentinelAlertRuleTemplateId{
SubscriptionId: "12345678-1234-9876-4563-123456789012",
ResourceGroup: "resGroup1",
WorkspaceName: "workspace1",
AlertRuleTemplateName: "template1",
},
},

{
// upper-cased
Input: "/SUBSCRIPTIONS/12345678-1234-9876-4563-123456789012/RESOURCEGROUPS/RESGROUP1/PROVIDERS/MICROSOFT.OPERATIONALINSIGHTS/WORKSPACES/WORKSPACE1/PROVIDERS/MICROSOFT.SECURITYINSIGHTS/ALERTRULETEMPLATES/TEMPLATE1",
Error: true,
},
}

for _, v := range testData {
t.Logf("[DEBUG] Testing %q", v.Input)

actual, err := SentinelAlertRuleTemplateID(v.Input)
if err != nil {
if v.Error {
continue
}

t.Fatalf("Expect a value but got an error: %s", err)
}
if v.Error {
t.Fatal("Expect an error but didn't get one")
}

if actual.SubscriptionId != v.Expected.SubscriptionId {
t.Fatalf("Expected %q but got %q for SubscriptionId", v.Expected.SubscriptionId, actual.SubscriptionId)
}
if actual.ResourceGroup != v.Expected.ResourceGroup {
t.Fatalf("Expected %q but got %q for ResourceGroup", v.Expected.ResourceGroup, actual.ResourceGroup)
}
if actual.WorkspaceName != v.Expected.WorkspaceName {
t.Fatalf("Expected %q but got %q for WorkspaceName", v.Expected.WorkspaceName, actual.WorkspaceName)
}
if actual.AlertRuleTemplateName != v.Expected.AlertRuleTemplateName {
t.Fatalf("Expected %q but got %q for AlertRuleTemplateName", v.Expected.AlertRuleTemplateName, actual.AlertRuleTemplateName)
}
}
}
3 changes: 2 additions & 1 deletion azurerm/internal/services/sentinel/registration.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,8 @@ func (r Registration) WebsiteCategories() []string {
// SupportedDataSources returns the supported Data Sources supported by this Service
func (r Registration) SupportedDataSources() map[string]*schema.Resource {
return map[string]*schema.Resource{
"azurerm_sentinel_alert_rule": dataSourceSentinelAlertRule(),
"azurerm_sentinel_alert_rule": dataSourceSentinelAlertRule(),
"azurerm_sentinel_alert_rule_template": dataSourceSentinelAlertRuleTemplate(),
}
}

Expand Down
3 changes: 3 additions & 0 deletions azurerm/internal/services/sentinel/resourceids.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
package sentinel

//go:generate go run ../../tools/generator-resource-id/main.go -path=./ -name=SentinelAlertRuleTemplate -id=/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/resGroup1/providers/Microsoft.OperationalInsights/workspaces/workspace1/providers/Microsoft.SecurityInsights/AlertRuleTemplates/template1
Original file line number Diff line number Diff line change
Expand Up @@ -113,10 +113,15 @@ func (r SentinelAlertRuleFusionResource) basic(data acceptance.TestData) string
return fmt.Sprintf(`
%s
data "azurerm_sentinel_alert_rule_template" "test" {
display_name = "Advanced Multistage Attack Detection"
log_analytics_workspace_id = azurerm_log_analytics_workspace.test.id
}
resource "azurerm_sentinel_alert_rule_fusion" "test" {
name = "acctest-SentinelAlertRule-Fusion-%d"
log_analytics_workspace_id = azurerm_log_analytics_workspace.test.id
alert_rule_template_guid = "f71aba3d-28fb-450b-b192-4e76a83015c8"
alert_rule_template_guid = data.azurerm_sentinel_alert_rule_template.test.name
}
`, r.template(data), data.RandomInteger)
}
Expand All @@ -125,10 +130,15 @@ func (r SentinelAlertRuleFusionResource) complete(data acceptance.TestData) stri
return fmt.Sprintf(`
%s
data "azurerm_sentinel_alert_rule_template" "test" {
display_name = "Advanced Multistage Attack Detection"
log_analytics_workspace_id = azurerm_log_analytics_workspace.test.id
}
resource "azurerm_sentinel_alert_rule_fusion" "test" {
name = "acctest-SentinelAlertRule-Fusion-%d"
log_analytics_workspace_id = azurerm_log_analytics_workspace.test.id
alert_rule_template_guid = "f71aba3d-28fb-450b-b192-4e76a83015c8"
alert_rule_template_guid = data.azurerm_sentinel_alert_rule_template.test.name
enabled = false
}
`, r.template(data), data.RandomInteger)
Expand Down

0 comments on commit 2e7f23c

Please sign in to comment.