From 1021e6f84acc86a3856bb7cc15b64c6844e69318 Mon Sep 17 00:00:00 2001 From: Zhenhua Hu Date: Fri, 29 Jul 2022 07:06:10 +0800 Subject: [PATCH] New Resource: azurerm_logz_sub_account_tag_rule (#17557) --- internal/services/logz/client/client.go | 17 +- internal/services/logz/logz_common.go | 33 +++ .../logz_sub_account_tag_rule_resource.go | 154 +++++++++++++ ...logz_sub_account_tag_rule_resource_test.go | 204 ++++++++++++++++++ .../services/logz/logz_tag_rule_resource.go | 34 +-- .../logz/parse/logz_sub_account_tag_rule.go | 81 +++++++ .../parse/logz_sub_account_tag_rule_test.go | 144 +++++++++++++ internal/services/logz/registration.go | 7 +- internal/services/logz/resourceids.go | 1 + .../validate/logz_sub_account_tag_rule_id.go | 23 ++ .../logz_sub_account_tag_rule_id_test.go | 100 +++++++++ .../r/logz_sub_account_tag_rule.html.markdown | 119 ++++++++++ 12 files changed, 876 insertions(+), 41 deletions(-) create mode 100644 internal/services/logz/logz_sub_account_tag_rule_resource.go create mode 100644 internal/services/logz/logz_sub_account_tag_rule_resource_test.go create mode 100644 internal/services/logz/parse/logz_sub_account_tag_rule.go create mode 100644 internal/services/logz/parse/logz_sub_account_tag_rule_test.go create mode 100644 internal/services/logz/validate/logz_sub_account_tag_rule_id.go create mode 100644 internal/services/logz/validate/logz_sub_account_tag_rule_id_test.go create mode 100644 website/docs/r/logz_sub_account_tag_rule.html.markdown diff --git a/internal/services/logz/client/client.go b/internal/services/logz/client/client.go index ff2e19423bee..ee1d772446a9 100644 --- a/internal/services/logz/client/client.go +++ b/internal/services/logz/client/client.go @@ -6,9 +6,10 @@ import ( ) type Client struct { - MonitorClient *logz.MonitorsClient - TagRuleClient *logz.TagRulesClient - SubAccountClient *logz.SubAccountClient + MonitorClient *logz.MonitorsClient + TagRuleClient *logz.TagRulesClient + SubAccountClient *logz.SubAccountClient + SubAccountTagRuleClient *logz.SubAccountTagRulesClient } func NewClient(o *common.ClientOptions) *Client { @@ -21,9 +22,13 @@ func NewClient(o *common.ClientOptions) *Client { subAccountClient := logz.NewSubAccountClientWithBaseURI(o.ResourceManagerEndpoint, o.SubscriptionId) o.ConfigureClient(&subAccountClient.Client, o.ResourceManagerAuthorizer) + subAccountTagRuleClient := logz.NewSubAccountTagRulesClientWithBaseURI(o.ResourceManagerEndpoint, o.SubscriptionId) + o.ConfigureClient(&subAccountTagRuleClient.Client, o.ResourceManagerAuthorizer) + return &Client{ - MonitorClient: &monitorClient, - TagRuleClient: &tagRuleClient, - SubAccountClient: &subAccountClient, + MonitorClient: &monitorClient, + TagRuleClient: &tagRuleClient, + SubAccountClient: &subAccountClient, + SubAccountTagRuleClient: &subAccountTagRuleClient, } } diff --git a/internal/services/logz/logz_common.go b/internal/services/logz/logz_common.go index e51f9321a8ee..2a603b2e4a8f 100644 --- a/internal/services/logz/logz_common.go +++ b/internal/services/logz/logz_common.go @@ -7,6 +7,8 @@ import ( "github.com/hashicorp/terraform-provider-azurerm/utils" ) +const TagRuleName = "default" + func SchemaUserInfo() *pluginsdk.Schema { return &pluginsdk.Schema{ Type: pluginsdk.TypeList, @@ -95,3 +97,34 @@ func flattenUserInfo(input *logz.UserInfo) []interface{} { }, } } + +func schemaTagFilter() *pluginsdk.Schema { + return &pluginsdk.Schema{ + Type: pluginsdk.TypeList, + Optional: true, + MaxItems: 10, + Elem: &pluginsdk.Resource{ + Schema: map[string]*pluginsdk.Schema{ + "name": { + Type: pluginsdk.TypeString, + Required: true, + ValidateFunc: validation.StringIsNotEmpty, + }, + + "action": { + Type: pluginsdk.TypeString, + Required: true, + ValidateFunc: validation.StringInSlice([]string{ + string(logz.TagActionInclude), + string(logz.TagActionExclude), + }, false), + }, + + "value": { + Type: pluginsdk.TypeString, + Optional: true, + }, + }, + }, + } +} diff --git a/internal/services/logz/logz_sub_account_tag_rule_resource.go b/internal/services/logz/logz_sub_account_tag_rule_resource.go new file mode 100644 index 000000000000..4cb65c0f719d --- /dev/null +++ b/internal/services/logz/logz_sub_account_tag_rule_resource.go @@ -0,0 +1,154 @@ +package logz + +import ( + "fmt" + "log" + "time" + + "github.com/Azure/azure-sdk-for-go/services/logz/mgmt/2020-10-01/logz" + "github.com/hashicorp/terraform-provider-azurerm/helpers/tf" + "github.com/hashicorp/terraform-provider-azurerm/internal/clients" + "github.com/hashicorp/terraform-provider-azurerm/internal/services/logz/parse" + "github.com/hashicorp/terraform-provider-azurerm/internal/services/logz/validate" + "github.com/hashicorp/terraform-provider-azurerm/internal/tf/pluginsdk" + "github.com/hashicorp/terraform-provider-azurerm/internal/timeouts" + "github.com/hashicorp/terraform-provider-azurerm/utils" +) + +func resourceLogzSubAccountTagRule() *pluginsdk.Resource { + return &pluginsdk.Resource{ + Create: resourceLogzSubAccountTagRuleCreateUpdate, + Read: resourceLogzSubAccountTagRuleRead, + Update: resourceLogzSubAccountTagRuleCreateUpdate, + Delete: resourceLogzSubAccountTagRuleDelete, + + Timeouts: &pluginsdk.ResourceTimeout{ + Create: pluginsdk.DefaultTimeout(30 * time.Minute), + Read: pluginsdk.DefaultTimeout(5 * time.Minute), + Update: pluginsdk.DefaultTimeout(30 * time.Minute), + Delete: pluginsdk.DefaultTimeout(30 * time.Minute), + }, + + Importer: pluginsdk.ImporterValidatingResourceId(func(id string) error { + _, err := parse.LogzSubAccountTagRuleID(id) + return err + }), + + Schema: map[string]*pluginsdk.Schema{ + "logz_sub_account_id": { + Type: pluginsdk.TypeString, + Required: true, + ForceNew: true, + ValidateFunc: validate.LogzSubAccountID, + }, + + "tag_filter": schemaTagFilter(), + + "send_aad_logs": { + Type: pluginsdk.TypeBool, + Optional: true, + Default: false, + }, + + "send_activity_logs": { + Type: pluginsdk.TypeBool, + Optional: true, + Default: false, + }, + + "send_subscription_logs": { + Type: pluginsdk.TypeBool, + Optional: true, + Default: false, + }, + }, + } +} +func resourceLogzSubAccountTagRuleCreateUpdate(d *pluginsdk.ResourceData, meta interface{}) error { + client := meta.(*clients.Client).Logz.SubAccountTagRuleClient + ctx, cancel := timeouts.ForCreateUpdate(meta.(*clients.Client).StopContext, d) + defer cancel() + + subAccountId, err := parse.LogzSubAccountID(d.Get("logz_sub_account_id").(string)) + if err != nil { + return err + } + + id := parse.NewLogzSubAccountTagRuleID(subAccountId.SubscriptionId, subAccountId.ResourceGroup, subAccountId.MonitorName, subAccountId.AccountName, TagRuleName) + + if d.IsNewResource() { + existing, err := client.Get(ctx, id.ResourceGroup, id.MonitorName, id.AccountName, id.TagRuleName) + if err != nil { + if !utils.ResponseWasNotFound(existing.Response) { + return fmt.Errorf("checking for existing %s: %+v", id, err) + } + } + if existing.ID != nil && *existing.ID != "" { + return tf.ImportAsExistsError("azurerm_logz_sub_account_tag_rule", *existing.ID) + } + } + + props := logz.MonitoringTagRules{ + Properties: &logz.MonitoringTagRulesProperties{ + LogRules: expandTagRuleLogRules(d), + }, + } + + if _, err := client.CreateOrUpdate(ctx, id.ResourceGroup, id.MonitorName, id.AccountName, id.TagRuleName, &props); err != nil { + return fmt.Errorf("creating/updating %s: %+v", id, err) + } + + d.SetId(id.ID()) + return resourceLogzSubAccountTagRuleRead(d, meta) +} + +func resourceLogzSubAccountTagRuleRead(d *pluginsdk.ResourceData, meta interface{}) error { + client := meta.(*clients.Client).Logz.SubAccountTagRuleClient + ctx, cancel := timeouts.ForRead(meta.(*clients.Client).StopContext, d) + defer cancel() + + id, err := parse.LogzSubAccountTagRuleID(d.Id()) + if err != nil { + return err + } + + resp, err := client.Get(ctx, id.ResourceGroup, id.MonitorName, id.AccountName, id.TagRuleName) + if err != nil { + if utils.ResponseWasNotFound(resp.Response) { + log.Printf("[INFO] logz %q does not exist - removing from state", d.Id()) + d.SetId("") + return nil + } + return fmt.Errorf("retrieving %s: %+v", id, err) + } + + d.Set("logz_sub_account_id", parse.NewLogzSubAccountID(id.SubscriptionId, id.ResourceGroup, id.MonitorName, id.AccountName).ID()) + if props := resp.Properties; props != nil && props.LogRules != nil { + d.Set("send_aad_logs", props.LogRules.SendAadLogs) + d.Set("send_activity_logs", props.LogRules.SendActivityLogs) + d.Set("send_subscription_logs", props.LogRules.SendSubscriptionLogs) + + if err := d.Set("tag_filter", flattenTagRuleFilteringTagArray(props.LogRules.FilteringTags)); err != nil { + return fmt.Errorf("setting `tag_filter`: %+v", err) + } + } + + return nil +} + +func resourceLogzSubAccountTagRuleDelete(d *pluginsdk.ResourceData, meta interface{}) error { + client := meta.(*clients.Client).Logz.SubAccountTagRuleClient + ctx, cancel := timeouts.ForDelete(meta.(*clients.Client).StopContext, d) + defer cancel() + + id, err := parse.LogzSubAccountTagRuleID(d.Id()) + if err != nil { + return err + } + + if _, err := client.Delete(ctx, id.ResourceGroup, id.MonitorName, id.AccountName, id.TagRuleName); err != nil { + return fmt.Errorf("deleting %s: %+v", id, err) + } + + return nil +} diff --git a/internal/services/logz/logz_sub_account_tag_rule_resource_test.go b/internal/services/logz/logz_sub_account_tag_rule_resource_test.go new file mode 100644 index 000000000000..8e620c893d15 --- /dev/null +++ b/internal/services/logz/logz_sub_account_tag_rule_resource_test.go @@ -0,0 +1,204 @@ +package logz_test + +import ( + "context" + "fmt" + "testing" + + "github.com/hashicorp/terraform-provider-azurerm/internal/acceptance" + "github.com/hashicorp/terraform-provider-azurerm/internal/acceptance/check" + "github.com/hashicorp/terraform-provider-azurerm/internal/clients" + "github.com/hashicorp/terraform-provider-azurerm/internal/services/logz/parse" + "github.com/hashicorp/terraform-provider-azurerm/internal/tf/pluginsdk" + "github.com/hashicorp/terraform-provider-azurerm/utils" +) + +type LogzSubAccountTagRuleResource struct{} + +func TestAccLogzSubAccountTagRule_basic(t *testing.T) { + data := acceptance.BuildTestData(t, "azurerm_logz_sub_account_tag_rule", "test") + r := LogzSubAccountTagRuleResource{} + email := "72776074-85d8-47fc-a1c2-cd23693522da@example.com" + data.ResourceTest(t, r, []acceptance.TestStep{ + { + Config: r.basic(data, email), + Check: acceptance.ComposeTestCheckFunc( + check.That(data.ResourceName).ExistsInAzure(r), + ), + }, + data.ImportStep(), + }) +} + +func TestAccLogzSubAccountTagRule_requiresImport(t *testing.T) { + data := acceptance.BuildTestData(t, "azurerm_logz_sub_account_tag_rule", "test") + r := LogzSubAccountTagRuleResource{} + email := "59cb83fc-bb49-414b-8762-e5cd463f1463@example.com" + data.ResourceTest(t, r, []acceptance.TestStep{ + { + Config: r.basic(data, email), + Check: acceptance.ComposeTestCheckFunc( + check.That(data.ResourceName).ExistsInAzure(r), + ), + }, + { + Config: r.requiresImport(data, email), + ExpectError: acceptance.RequiresImportError(data.ResourceType), + }, + }) +} + +func TestAccLogzSubAccountTagRule_complete(t *testing.T) { + data := acceptance.BuildTestData(t, "azurerm_logz_sub_account_tag_rule", "test") + r := LogzSubAccountTagRuleResource{} + email := "77e97659-200c-41f1-824d-f596c9566aee@example.com" + data.ResourceTest(t, r, []acceptance.TestStep{ + { + Config: r.complete(data, email), + Check: acceptance.ComposeTestCheckFunc( + check.That(data.ResourceName).ExistsInAzure(r), + ), + }, + data.ImportStep(), + }) +} + +func TestAccLogzSubAccountTagRule_update(t *testing.T) { + data := acceptance.BuildTestData(t, "azurerm_logz_sub_account_tag_rule", "test") + r := LogzSubAccountTagRuleResource{} + email := "a9c283cf-9045-40f0-aecf-d8738e5ed103@example.com" + data.ResourceTest(t, r, []acceptance.TestStep{ + { + Config: r.basic(data, email), + Check: acceptance.ComposeTestCheckFunc( + check.That(data.ResourceName).ExistsInAzure(r), + ), + }, + data.ImportStep(), + { + Config: r.complete(data, email), + Check: acceptance.ComposeTestCheckFunc( + check.That(data.ResourceName).ExistsInAzure(r), + ), + }, + data.ImportStep(), + { + Config: r.basic(data, email), + Check: acceptance.ComposeTestCheckFunc( + check.That(data.ResourceName).ExistsInAzure(r), + ), + }, + data.ImportStep(), + }) +} + +func (r LogzSubAccountTagRuleResource) Exists(ctx context.Context, clients *clients.Client, state *pluginsdk.InstanceState) (*bool, error) { + id, err := parse.LogzSubAccountTagRuleID(state.ID) + if err != nil { + return nil, err + } + resp, err := clients.Logz.SubAccountTagRuleClient.Get(ctx, id.ResourceGroup, id.MonitorName, id.AccountName, id.TagRuleName) + if err != nil { + if utils.ResponseWasNotFound(resp.Response) { + return utils.Bool(false), nil + } + return nil, fmt.Errorf("retrieving %s: %+v", id, err) + } + return utils.Bool(true), nil +} + +func (r LogzSubAccountTagRuleResource) template(data acceptance.TestData, email string) string { + return fmt.Sprintf(` +provider "azurerm" { + features {} +} + +resource "azurerm_resource_group" "test" { + name = "acctest-logz-%d" + location = "%s" +} + +resource "azurerm_logz_monitor" "test" { + name = "acctest-lm-%d" + resource_group_name = azurerm_resource_group.test.name + location = azurerm_resource_group.test.location + plan { + billing_cycle = "MONTHLY" + effective_date = "%s" + plan_id = "100gb14days" + usage_type = "COMMITTED" + } + + user { + email = "%s" + first_name = "first" + last_name = "last" + phone_number = "123456" + } +} + +resource "azurerm_logz_sub_account" "test" { + name = "acctest-lsa-%d" + logz_monitor_id = azurerm_logz_monitor.test.id + user { + email = azurerm_logz_monitor.test.user[0].email + first_name = azurerm_logz_monitor.test.user[0].first_name + last_name = azurerm_logz_monitor.test.user[0].last_name + phone_number = azurerm_logz_monitor.test.user[0].phone_number + } +} +`, data.RandomInteger, data.Locations.Primary, data.RandomInteger, getEffectiveDate(), email, data.RandomInteger) +} + +func (r LogzSubAccountTagRuleResource) basic(data acceptance.TestData, email string) string { + template := r.template(data, email) + return fmt.Sprintf(` +%s + +resource "azurerm_logz_sub_account_tag_rule" "test" { + logz_sub_account_id = azurerm_logz_sub_account.test.id +} +`, template) +} + +func (r LogzSubAccountTagRuleResource) requiresImport(data acceptance.TestData, email string) string { + config := r.basic(data, email) + return fmt.Sprintf(` +%s + +resource "azurerm_logz_sub_account_tag_rule" "import" { + logz_sub_account_id = azurerm_logz_sub_account_tag_rule.test.logz_sub_account_id +} +`, config) +} + +func (r LogzSubAccountTagRuleResource) complete(data acceptance.TestData, email string) string { + template := r.template(data, email) + return fmt.Sprintf(` +%s + +resource "azurerm_logz_sub_account_tag_rule" "test" { + logz_sub_account_id = azurerm_logz_sub_account.test.id + tag_filter { + name = "ccc" + action = "Include" + value = "ccc" + } + + tag_filter { + name = "bbb" + action = "Exclude" + value = "" + } + + tag_filter { + name = "ccc" + action = "Include" + value = "ccc" + } + send_aad_logs = true + send_activity_logs = true + send_subscription_logs = true +} +`, template) +} diff --git a/internal/services/logz/logz_tag_rule_resource.go b/internal/services/logz/logz_tag_rule_resource.go index 79bc8c858c5e..8c282ca1f50d 100644 --- a/internal/services/logz/logz_tag_rule_resource.go +++ b/internal/services/logz/logz_tag_rule_resource.go @@ -11,13 +11,10 @@ import ( "github.com/hashicorp/terraform-provider-azurerm/internal/services/logz/parse" "github.com/hashicorp/terraform-provider-azurerm/internal/services/logz/validate" "github.com/hashicorp/terraform-provider-azurerm/internal/tf/pluginsdk" - "github.com/hashicorp/terraform-provider-azurerm/internal/tf/validation" "github.com/hashicorp/terraform-provider-azurerm/internal/timeouts" "github.com/hashicorp/terraform-provider-azurerm/utils" ) -const tagRuleName = "default" - func resourceLogzTagRule() *pluginsdk.Resource { return &pluginsdk.Resource{ Create: resourceLogzTagRuleCreateUpdate, @@ -45,34 +42,7 @@ func resourceLogzTagRule() *pluginsdk.Resource { ValidateFunc: validate.LogzMonitorID, }, - "tag_filter": { - Type: pluginsdk.TypeList, - Optional: true, - MaxItems: 10, - Elem: &pluginsdk.Resource{ - Schema: map[string]*pluginsdk.Schema{ - "name": { - Type: pluginsdk.TypeString, - Required: true, - ValidateFunc: validation.StringIsNotEmpty, - }, - - "action": { - Type: pluginsdk.TypeString, - Required: true, - ValidateFunc: validation.StringInSlice([]string{ - string(logz.TagActionInclude), - string(logz.TagActionExclude), - }, false), - }, - - "value": { - Type: pluginsdk.TypeString, - Optional: true, - }, - }, - }, - }, + "tag_filter": schemaTagFilter(), "send_aad_logs": { Type: pluginsdk.TypeBool, @@ -105,7 +75,7 @@ func resourceLogzTagRuleCreateUpdate(d *pluginsdk.ResourceData, meta interface{} return err } - id := parse.NewLogzTagRuleID(monitorId.SubscriptionId, monitorId.ResourceGroup, monitorId.MonitorName, tagRuleName) + id := parse.NewLogzTagRuleID(monitorId.SubscriptionId, monitorId.ResourceGroup, monitorId.MonitorName, TagRuleName) if d.IsNewResource() { existing, err := client.Get(ctx, id.ResourceGroup, id.MonitorName, id.TagRuleName) diff --git a/internal/services/logz/parse/logz_sub_account_tag_rule.go b/internal/services/logz/parse/logz_sub_account_tag_rule.go new file mode 100644 index 000000000000..763747b347bb --- /dev/null +++ b/internal/services/logz/parse/logz_sub_account_tag_rule.go @@ -0,0 +1,81 @@ +package parse + +// NOTE: this file is generated via 'go:generate' - manual changes will be overwritten + +import ( + "fmt" + "strings" + + "github.com/hashicorp/go-azure-helpers/resourcemanager/resourceids" +) + +type LogzSubAccountTagRuleId struct { + SubscriptionId string + ResourceGroup string + MonitorName string + AccountName string + TagRuleName string +} + +func NewLogzSubAccountTagRuleID(subscriptionId, resourceGroup, monitorName, accountName, tagRuleName string) LogzSubAccountTagRuleId { + return LogzSubAccountTagRuleId{ + SubscriptionId: subscriptionId, + ResourceGroup: resourceGroup, + MonitorName: monitorName, + AccountName: accountName, + TagRuleName: tagRuleName, + } +} + +func (id LogzSubAccountTagRuleId) String() string { + segments := []string{ + fmt.Sprintf("Tag Rule Name %q", id.TagRuleName), + fmt.Sprintf("Account Name %q", id.AccountName), + fmt.Sprintf("Monitor Name %q", id.MonitorName), + fmt.Sprintf("Resource Group %q", id.ResourceGroup), + } + segmentsStr := strings.Join(segments, " / ") + return fmt.Sprintf("%s: (%s)", "Logz Sub Account Tag Rule", segmentsStr) +} + +func (id LogzSubAccountTagRuleId) ID() string { + fmtString := "/subscriptions/%s/resourceGroups/%s/providers/Microsoft.Logz/monitors/%s/accounts/%s/tagRules/%s" + return fmt.Sprintf(fmtString, id.SubscriptionId, id.ResourceGroup, id.MonitorName, id.AccountName, id.TagRuleName) +} + +// LogzSubAccountTagRuleID parses a LogzSubAccountTagRule ID into an LogzSubAccountTagRuleId struct +func LogzSubAccountTagRuleID(input string) (*LogzSubAccountTagRuleId, error) { + id, err := resourceids.ParseAzureResourceID(input) + if err != nil { + return nil, err + } + + resourceId := LogzSubAccountTagRuleId{ + 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.MonitorName, err = id.PopSegment("monitors"); err != nil { + return nil, err + } + if resourceId.AccountName, err = id.PopSegment("accounts"); err != nil { + return nil, err + } + if resourceId.TagRuleName, err = id.PopSegment("tagRules"); err != nil { + return nil, err + } + + if err := id.ValidateNoEmptySegments(input); err != nil { + return nil, err + } + + return &resourceId, nil +} diff --git a/internal/services/logz/parse/logz_sub_account_tag_rule_test.go b/internal/services/logz/parse/logz_sub_account_tag_rule_test.go new file mode 100644 index 000000000000..353ff2156a8c --- /dev/null +++ b/internal/services/logz/parse/logz_sub_account_tag_rule_test.go @@ -0,0 +1,144 @@ +package parse + +// NOTE: this file is generated via 'go:generate' - manual changes will be overwritten + +import ( + "testing" + + "github.com/hashicorp/go-azure-helpers/resourcemanager/resourceids" +) + +var _ resourceids.Id = LogzSubAccountTagRuleId{} + +func TestLogzSubAccountTagRuleIDFormatter(t *testing.T) { + actual := NewLogzSubAccountTagRuleID("12345678-1234-9876-4563-123456789012", "resourceGroup1", "monitor1", "subAccount1", "ruleSet1").ID() + expected := "/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/resourceGroup1/providers/Microsoft.Logz/monitors/monitor1/accounts/subAccount1/tagRules/ruleSet1" + if actual != expected { + t.Fatalf("Expected %q but got %q", expected, actual) + } +} + +func TestLogzSubAccountTagRuleID(t *testing.T) { + testData := []struct { + Input string + Error bool + Expected *LogzSubAccountTagRuleId + }{ + + { + // 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 MonitorName + Input: "/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/resourceGroup1/providers/Microsoft.Logz/", + Error: true, + }, + + { + // missing value for MonitorName + Input: "/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/resourceGroup1/providers/Microsoft.Logz/monitors/", + Error: true, + }, + + { + // missing AccountName + Input: "/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/resourceGroup1/providers/Microsoft.Logz/monitors/monitor1/", + Error: true, + }, + + { + // missing value for AccountName + Input: "/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/resourceGroup1/providers/Microsoft.Logz/monitors/monitor1/accounts/", + Error: true, + }, + + { + // missing TagRuleName + Input: "/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/resourceGroup1/providers/Microsoft.Logz/monitors/monitor1/accounts/subAccount1/", + Error: true, + }, + + { + // missing value for TagRuleName + Input: "/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/resourceGroup1/providers/Microsoft.Logz/monitors/monitor1/accounts/subAccount1/tagRules/", + Error: true, + }, + + { + // valid + Input: "/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/resourceGroup1/providers/Microsoft.Logz/monitors/monitor1/accounts/subAccount1/tagRules/ruleSet1", + Expected: &LogzSubAccountTagRuleId{ + SubscriptionId: "12345678-1234-9876-4563-123456789012", + ResourceGroup: "resourceGroup1", + MonitorName: "monitor1", + AccountName: "subAccount1", + TagRuleName: "ruleSet1", + }, + }, + + { + // upper-cased + Input: "/SUBSCRIPTIONS/12345678-1234-9876-4563-123456789012/RESOURCEGROUPS/RESOURCEGROUP1/PROVIDERS/MICROSOFT.LOGZ/MONITORS/MONITOR1/ACCOUNTS/SUBACCOUNT1/TAGRULES/RULESET1", + Error: true, + }, + } + + for _, v := range testData { + t.Logf("[DEBUG] Testing %q", v.Input) + + actual, err := LogzSubAccountTagRuleID(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.MonitorName != v.Expected.MonitorName { + t.Fatalf("Expected %q but got %q for MonitorName", v.Expected.MonitorName, actual.MonitorName) + } + if actual.AccountName != v.Expected.AccountName { + t.Fatalf("Expected %q but got %q for AccountName", v.Expected.AccountName, actual.AccountName) + } + if actual.TagRuleName != v.Expected.TagRuleName { + t.Fatalf("Expected %q but got %q for TagRuleName", v.Expected.TagRuleName, actual.TagRuleName) + } + } +} diff --git a/internal/services/logz/registration.go b/internal/services/logz/registration.go index f3ee2a115025..7255a703c8f2 100644 --- a/internal/services/logz/registration.go +++ b/internal/services/logz/registration.go @@ -33,8 +33,9 @@ func (r Registration) SupportedDataSources() map[string]*pluginsdk.Resource { // SupportedResources returns the supported Resources supported by this Service func (r Registration) SupportedResources() map[string]*pluginsdk.Resource { return map[string]*pluginsdk.Resource{ - "azurerm_logz_monitor": resourceLogzMonitor(), - "azurerm_logz_tag_rule": resourceLogzTagRule(), - "azurerm_logz_sub_account": resourceLogzSubAccount(), + "azurerm_logz_monitor": resourceLogzMonitor(), + "azurerm_logz_tag_rule": resourceLogzTagRule(), + "azurerm_logz_sub_account": resourceLogzSubAccount(), + "azurerm_logz_sub_account_tag_rule": resourceLogzSubAccountTagRule(), } } diff --git a/internal/services/logz/resourceids.go b/internal/services/logz/resourceids.go index 229f947d4f71..657d0fc1e4f2 100644 --- a/internal/services/logz/resourceids.go +++ b/internal/services/logz/resourceids.go @@ -3,3 +3,4 @@ package logz //go:generate go run ../../tools/generator-resource-id/main.go -path=./ -name=LogzMonitor -id=/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/resourceGroup1/providers/Microsoft.Logz/monitors/monitor1 //go:generate go run ../../tools/generator-resource-id/main.go -path=./ -name=LogzTagRule -id=/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/resourceGroup1/providers/Microsoft.Logz/monitors/monitor1/tagRules/ruleSet1 //go:generate go run ../../tools/generator-resource-id/main.go -path=./ -name=LogzSubAccount -id=/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/resourceGroup1/providers/Microsoft.Logz/monitors/monitor1/accounts/subAccount1 +//go:generate go run ../../tools/generator-resource-id/main.go -path=./ -name=LogzSubAccountTagRule -id=/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/resourceGroup1/providers/Microsoft.Logz/monitors/monitor1/accounts/subAccount1/tagRules/ruleSet1 diff --git a/internal/services/logz/validate/logz_sub_account_tag_rule_id.go b/internal/services/logz/validate/logz_sub_account_tag_rule_id.go new file mode 100644 index 000000000000..41d6fb8afe90 --- /dev/null +++ b/internal/services/logz/validate/logz_sub_account_tag_rule_id.go @@ -0,0 +1,23 @@ +package validate + +// NOTE: this file is generated via 'go:generate' - manual changes will be overwritten + +import ( + "fmt" + + "github.com/hashicorp/terraform-provider-azurerm/internal/services/logz/parse" +) + +func LogzSubAccountTagRuleID(input interface{}, key string) (warnings []string, errors []error) { + v, ok := input.(string) + if !ok { + errors = append(errors, fmt.Errorf("expected %q to be a string", key)) + return + } + + if _, err := parse.LogzSubAccountTagRuleID(v); err != nil { + errors = append(errors, err) + } + + return +} diff --git a/internal/services/logz/validate/logz_sub_account_tag_rule_id_test.go b/internal/services/logz/validate/logz_sub_account_tag_rule_id_test.go new file mode 100644 index 000000000000..cd237500a80c --- /dev/null +++ b/internal/services/logz/validate/logz_sub_account_tag_rule_id_test.go @@ -0,0 +1,100 @@ +package validate + +// NOTE: this file is generated via 'go:generate' - manual changes will be overwritten + +import "testing" + +func TestLogzSubAccountTagRuleID(t *testing.T) { + cases := []struct { + Input string + Valid bool + }{ + + { + // empty + Input: "", + Valid: false, + }, + + { + // missing SubscriptionId + Input: "/", + Valid: false, + }, + + { + // missing value for SubscriptionId + Input: "/subscriptions/", + Valid: false, + }, + + { + // missing ResourceGroup + Input: "/subscriptions/12345678-1234-9876-4563-123456789012/", + Valid: false, + }, + + { + // missing value for ResourceGroup + Input: "/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/", + Valid: false, + }, + + { + // missing MonitorName + Input: "/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/resourceGroup1/providers/Microsoft.Logz/", + Valid: false, + }, + + { + // missing value for MonitorName + Input: "/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/resourceGroup1/providers/Microsoft.Logz/monitors/", + Valid: false, + }, + + { + // missing AccountName + Input: "/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/resourceGroup1/providers/Microsoft.Logz/monitors/monitor1/", + Valid: false, + }, + + { + // missing value for AccountName + Input: "/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/resourceGroup1/providers/Microsoft.Logz/monitors/monitor1/accounts/", + Valid: false, + }, + + { + // missing TagRuleName + Input: "/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/resourceGroup1/providers/Microsoft.Logz/monitors/monitor1/accounts/subAccount1/", + Valid: false, + }, + + { + // missing value for TagRuleName + Input: "/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/resourceGroup1/providers/Microsoft.Logz/monitors/monitor1/accounts/subAccount1/tagRules/", + Valid: false, + }, + + { + // valid + Input: "/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/resourceGroup1/providers/Microsoft.Logz/monitors/monitor1/accounts/subAccount1/tagRules/ruleSet1", + Valid: true, + }, + + { + // upper-cased + Input: "/SUBSCRIPTIONS/12345678-1234-9876-4563-123456789012/RESOURCEGROUPS/RESOURCEGROUP1/PROVIDERS/MICROSOFT.LOGZ/MONITORS/MONITOR1/ACCOUNTS/SUBACCOUNT1/TAGRULES/RULESET1", + Valid: false, + }, + } + for _, tc := range cases { + t.Logf("[DEBUG] Testing Value %s", tc.Input) + _, errors := LogzSubAccountTagRuleID(tc.Input, "test") + valid := len(errors) == 0 + + if tc.Valid != valid { + t.Fatalf("Expected %t but got %t", tc.Valid, valid) + } + } +} diff --git a/website/docs/r/logz_sub_account_tag_rule.html.markdown b/website/docs/r/logz_sub_account_tag_rule.html.markdown new file mode 100644 index 000000000000..412a8d838dd4 --- /dev/null +++ b/website/docs/r/logz_sub_account_tag_rule.html.markdown @@ -0,0 +1,119 @@ +--- +subcategory: "Logz" +layout: "azurerm" +page_title: "Azure Resource Manager: azurerm_logz_sub_account_tag_rule" +description: |- + Manages a Logz Sub Account Tag Rule. +--- + +# azurerm_logz_sub_account_tag_rule + +Manages a Logz Sub Account Tag Rule. + +## Example Usage + +```hcl +resource "azurerm_resource_group" "example" { + name = "example-logz" + location = "West Europe" +} + +resource "azurerm_logz_monitor" "example" { + name = "example-monitor" + resource_group_name = azurerm_resource_group.example.name + location = azurerm_resource_group.example.location + plan { + billing_cycle = "MONTHLY" + effective_date = "2022-06-06T00:00:00Z" + plan_id = "100gb14days" + usage_type = "COMMITTED" + } + + user { + email = "user@example.com" + first_name = "Example" + last_name = "User" + phone_number = "+12313803556" + } +} + +resource "azurerm_logz_sub_account" "example" { + name = "example-subaccount" + logz_monitor_id = azurerm_logz_monitor.example.id + + user { + email = azurerm_logz_monitor.example.user[0].email + first_name = azurerm_logz_monitor.example.user[0].first_name + last_name = azurerm_logz_monitor.example.user[0].last_name + phone_number = azurerm_logz_monitor.example.user[0].phone_number + } +} + +resource "azurerm_logz_sub_account_tag_rule" "example" { + logz_sub_account_id = azurerm_logz_sub_account.example.id + send_aad_logs = true + send_activity_logs = true + send_subscription_logs = true + + tag_filter { + name = "name1" + action = "Include" + value = "value1" + } + + tag_filter { + name = "name2" + action = "Exclude" + value = "value2" + } +} +``` + +## Arguments Reference + +The following arguments are supported: + +* `logz_sub_account_id` - (Required) The ID of the Logz Sub Account. Changing this forces a new Logz Sub Account Tag Rule to be created. + +--- + +* `tag_filter` - (Optional) One or more (up to 10) `tag_filter` blocks as defined below. + +* `send_aad_logs` - (Optional) Whether AAD logs should be sent to the Monitor resource? + +* `send_activity_logs` - (Optional) Whether activity logs from this Logz Sub Account Tag Rule should be sent to the Monitor resource? + +* `send_subscription_logs` - (Optional) Whether subscription logs should be sent to the Monitor resource? + +--- + +An `tag_filter` block exports the following: + +* `name` - (Required) The name of the tag to match. + +* `action` - (Required) The action is used to limit logs collection to include or exclude Azure resources with specific tags. Possible values are `Include` and `Exclude`. Note that the `Exclude` takes priority over the `Include`. + +* `value` - (Optional) The value of the tag to match. + +## Attributes Reference + +In addition to the Arguments listed above - the following Attributes are exported: + +* `id` - The ID of the Logz Sub Account Tag Rule. + +## Timeouts + +The `timeouts` block allows you to specify [timeouts](https://www.terraform.io/docs/configuration/resources.html#timeouts) for certain actions: + +* `create` - (Defaults to 30 minutes) Used when creating the Logz Sub Account Tag Rule. +* `read` - (Defaults to 5 minutes) Used when retrieving the Logz Sub Account Tag Rule. +* `update` - (Defaults to 30 minutes) Used when updating the Logz Sub Account Tag Rule. +* `delete` - (Defaults to 30 minutes) Used when deleting the Logz Sub Account Tag Rule. + +## Import + +Logz Sub Account Tag Rules can be imported using the `resource id`, e.g. + +```shell +terraform import azurerm_logz_sub_account_tag_rule.example /subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/group1/providers/Microsoft.Logz/monitors/monitor1/accounts/subAccount1/tagRules/ruleSet1 +```