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

New Resource: azurerm_dynatrace_tag_rules #27985

Open
wants to merge 15 commits into
base: main
Choose a base branch
from
2 changes: 1 addition & 1 deletion .github/labeler-issue-triage.yml
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,7 @@ service/domain-services:
- '### (|New or )Affected Resource\(s\)\/Data Source\(s\)((.|\n)*)azurerm_active_directory_domain_service((.|\n)*)###'

service/dynatrace:
- '### (|New or )Affected Resource\(s\)\/Data Source\(s\)((.|\n)*)azurerm_dynatrace_monitor((.|\n)*)###'
- '### (|New or )Affected Resource\(s\)\/Data Source\(s\)((.|\n)*)azurerm_dynatrace_((.|\n)*)###'

service/elastic:
- '### (|New or )Affected Resource\(s\)\/Data Source\(s\)((.|\n)*)azurerm_elastic_cloud_elasticsearch((.|\n)*)###'
Expand Down
28 changes: 28 additions & 0 deletions internal/services/arckubernetes/log
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
2023-10-16T14:14:54.821+0800 [ERROR] sdk.helper_resource: Unexpected error: test_name=TestAccArcKubernetesClusterExtension_basic test_terraform_path=C:\ProgramData\chocolatey\bin\terraform.exe test_working_directory=C:\Users\JIAWEI~1\AppData\Local\Temp\plugintest4251856730
error=
| After applying this test step, the plan was not empty.
| stdout:
|
|
| Terraform used the selected providers to generate the following execution
| plan. Resource actions are indicated with the following symbols:
| ~ update in-place
|
| Terraform will perform the following actions:
|
| # azurerm_linux_virtual_machine.test will be updated in-place
| ~ resource "azurerm_linux_virtual_machine" "test" {
| id = "/subscriptions/85b3dbca-5974-4067-9669-67a141095a76/resourceGroups/acctestRG-231016140458737757/providers/Microsoft.Compute/virtualMachines/acctestVM-231016140458737757"
| name = "acctestVM-231016140458737757"
| ~ tags = {
| - "azsecpack" = "nonprod" -> null
| - "platformsettings.host_environment.service.platform_optedin_for_rootcerts" = "true" -> null
| }
| # (25 unchanged attributes hidden)
|
| # (2 unchanged blocks hidden)
| }
|
| Plan: 0 to add, 1 to change, 0 to destroy.
test_step_number=1
2023-10-16T14:14:57.712+0800 [WARN] sdk.helper_schema: Previously configured provider being re-configured. This can cause issues in concurrent testing if the configurations are not equal.: tf_rpc=Configure tf_req_id=337c8555-e8f2-4563-6fa4-cb805a25e160 tf_provider_addr=registry.terraform.io/hashicorp/azurerm
9 changes: 9 additions & 0 deletions internal/services/dynatrace/client/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,13 @@ import (
"fmt"

"github.com/hashicorp/go-azure-sdk/resource-manager/dynatrace/2023-04-27/monitors"
"github.com/hashicorp/go-azure-sdk/resource-manager/dynatrace/2023-04-27/tagrules"
"github.com/hashicorp/terraform-provider-azurerm/internal/common"
)

type Client struct {
*monitors.MonitorsClient
*tagrules.TagRulesClient
}

func NewClient(o *common.ClientOptions) (*Client, error) {
Expand All @@ -21,7 +23,14 @@ func NewClient(o *common.ClientOptions) (*Client, error) {
}
o.Configure(monitorClient.Client, o.Authorizers.ResourceManager)

tagruleClient, err := tagrules.NewTagRulesClientWithBaseURI(o.Environment.ResourceManager)
if err != nil {
return nil, fmt.Errorf("building Dynatrace TagRule client: %+v", err)
}
o.Configure(tagruleClient.Client, o.Authorizers.ResourceManager)

return &Client{
MonitorsClient: monitorClient,
TagRulesClient: tagruleClient,
}, nil
}
287 changes: 287 additions & 0 deletions internal/services/dynatrace/dynatrace_tag_rules_resource.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,287 @@
package dynatrace

import (
"context"
"fmt"
"time"

"github.com/hashicorp/go-azure-helpers/lang/response"
"github.com/hashicorp/go-azure-sdk/resource-manager/dynatrace/2023-04-27/monitors"
"github.com/hashicorp/go-azure-sdk/resource-manager/dynatrace/2023-04-27/tagrules"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
"github.com/hashicorp/terraform-provider-azurerm/internal/sdk"
"github.com/hashicorp/terraform-provider-azurerm/internal/tf/pluginsdk"
"github.com/hashicorp/terraform-provider-azurerm/internal/tf/validation"
)

type TagRulesResource struct{}

type TagRulesResourceModel struct {
Name string `tfschema:"name"`
Monitor string `tfschema:"monitor_id"`
LogRules []LogRule `tfschema:"log_rule"`
MetricRules []MetricRule `tfschema:"metric_rule"`
}

type MetricRule struct {
FilteringTags []FilteringTag `tfschema:"filtering_tag"`
}

type LogRule struct {
FilteringTags []FilteringTag `tfschema:"filtering_tag"`
SendAadLogs string `tfschema:"send_aad_logs"`
SendActivityLogs string `tfschema:"send_activity_logs"`
SendSubscriptionLogs string `tfschema:"send_subscription_logs"`
}

type FilteringTag struct {
Name string `tfschema:"name"`
Value string `tfschema:"value"`
Action string `tfschema:"action"`
}

func (r TagRulesResource) Arguments() map[string]*schema.Schema {
return map[string]*schema.Schema{
"name": {
Type: pluginsdk.TypeString,
Required: true,
ForceNew: true,
ValidateFunc: validation.StringIsNotEmpty,
},

"monitor_id": {
Type: pluginsdk.TypeString,
Required: true,
ForceNew: true,
ValidateFunc: monitors.ValidateMonitorID,
},

"log_rule": {
Type: pluginsdk.TypeList,
Optional: true,
ForceNew: true,
MaxItems: 1,
Elem: &pluginsdk.Resource{
Schema: map[string]*schema.Schema{
"send_aad_logs": {
Type: pluginsdk.TypeString,
Optional: true,
ValidateFunc: validation.StringInSlice([]string{
"Enabled",
"Disabled",
}, false),
},

"send_activity_logs": {
Type: pluginsdk.TypeString,
Optional: true,
ValidateFunc: validation.StringInSlice([]string{
"Enabled",
"Disabled",
}, false),
},

"send_subscription_logs": {
Type: pluginsdk.TypeString,
Optional: true,
ValidateFunc: validation.StringInSlice([]string{
"Enabled",
"Disabled",
}, false),
},

"filtering_tag": {
Type: pluginsdk.TypeList,
Required: true,
MinItems: 1,
Elem: &pluginsdk.Resource{
Schema: map[string]*schema.Schema{
"action": {
Type: pluginsdk.TypeString,
Required: true,
ValidateFunc: validation.StringInSlice([]string{
"Include",
"Exclude",
}, false),
},

"name": {
Type: pluginsdk.TypeString,
Required: true,
ValidateFunc: validation.StringIsNotEmpty,
},

"value": {
Type: pluginsdk.TypeString,
Required: true,
ValidateFunc: validation.StringIsNotEmpty,
},
},
},
},
},
},
},

"metric_rule": {
Type: pluginsdk.TypeList,
Optional: true,
ForceNew: true,
MaxItems: 1,
Elem: &pluginsdk.Resource{
Schema: map[string]*schema.Schema{
"filtering_tag": {
Type: pluginsdk.TypeList,
Required: true,
MinItems: 1,
Elem: &pluginsdk.Resource{
Schema: map[string]*schema.Schema{
"action": {
Type: pluginsdk.TypeString,
Required: true,
ValidateFunc: validation.StringInSlice([]string{
"Include",
"Exclude",
}, false),
},

"name": {
Type: pluginsdk.TypeString,
Required: true,
ValidateFunc: validation.StringIsNotEmpty,
},

"value": {
Type: pluginsdk.TypeString,
Required: true,
ValidateFunc: validation.StringIsNotEmpty,
},
},
},
},
},
},
},
}
}

func (r TagRulesResource) Attributes() map[string]*schema.Schema {
return map[string]*schema.Schema{}
}

func (r TagRulesResource) ModelObject() interface{} {
return &TagRulesResourceModel{}
}

func (r TagRulesResource) ResourceType() string {
return "azurerm_dynatrace_tag_rules"
}

func (r TagRulesResource) Create() sdk.ResourceFunc {
return sdk.ResourceFunc{
Timeout: 30 * time.Minute,
Func: func(ctx context.Context, metadata sdk.ResourceMetaData) error {
client := metadata.Client.Dynatrace.TagRulesClient
subscriptionId := metadata.Client.Account.SubscriptionId

var model TagRulesResourceModel
if err := metadata.Decode(&model); err != nil {
return err
}

monitorsId, err := monitors.ParseMonitorID(model.Monitor)
id := tagrules.NewTagRuleID(subscriptionId, monitorsId.ResourceGroupName, monitorsId.MonitorName, model.Name)
if err != nil {
return err
}

existing, err := client.Get(ctx, id)
if err != nil && !response.WasNotFound(existing.HttpResponse) {
return fmt.Errorf("checking for presence of existing %s: %+v", id, err)
}

if !response.WasNotFound(existing.HttpResponse) {
return metadata.ResourceRequiresImport(r.ResourceType(), id)
}

tagRulesProps := tagrules.MonitoringTagRulesProperties{
LogRules: ExpandLogRule(model.LogRules),
MetricRules: ExpandMetricRules(model.MetricRules),
}
tagRules := tagrules.TagRule{
Name: &model.Name,
Properties: tagRulesProps,
}

if _, err := client.CreateOrUpdate(ctx, id, tagRules); err != nil {
return fmt.Errorf("creating %s: %+v", id, err)
}

metadata.SetID(id)

return nil
},
}
}

func (r TagRulesResource) Read() sdk.ResourceFunc {
return sdk.ResourceFunc{
Timeout: 5 * time.Minute,
Func: func(ctx context.Context, metadata sdk.ResourceMetaData) error {
client := metadata.Client.Dynatrace.TagRulesClient
id, err := tagrules.ParseTagRuleID(metadata.ResourceData.Id())
if err != nil {
return err
}

resp, err := client.Get(ctx, *id)
if err != nil {
if response.WasNotFound(resp.HttpResponse) {
return metadata.MarkAsGone(id)
}
return fmt.Errorf("reading %s: %+v", id, err)
}
if model := resp.Model; model != nil {
props := model.Properties
monitorId := monitors.NewMonitorID(id.SubscriptionId, id.ResourceGroupName, id.MonitorName)

state := TagRulesResourceModel{
Name: id.TagRuleName,
Monitor: monitorId.ID(),
LogRules: FlattenLogRules(props.LogRules),
MetricRules: FlattenMetricRules(props.MetricRules),
}

return metadata.Encode(&state)
}

return nil
},
}
}

func (r TagRulesResource) Delete() sdk.ResourceFunc {
return sdk.ResourceFunc{
Timeout: 30 * time.Minute,
Func: func(ctx context.Context, metadata sdk.ResourceMetaData) error {
client := metadata.Client.Dynatrace.TagRulesClient
id, err := tagrules.ParseTagRuleID(metadata.ResourceData.Id())
if err != nil {
return err
}

metadata.Logger.Infof("deleting %s", *id)

if resp, err := client.Delete(ctx, *id); err != nil {
if !response.WasNotFound(resp.HttpResponse) {
return fmt.Errorf("deleting %s: %+v", *id, err)
}
}
return nil
},
}
}

func (r TagRulesResource) IDValidationFunc() pluginsdk.SchemaValidateFunc {
return tagrules.ValidateTagRuleID
}
Loading
Loading