From d1c636d7c6150d79750345f30d98f265ac298e8d Mon Sep 17 00:00:00 2001 From: Sherzod Karimov Date: Wed, 6 Nov 2024 10:52:55 -0500 Subject: [PATCH 01/10] generate boilerplate --- datadog/fwprovider/framework_provider.go | 1 + .../fwprovider/resource_datadog_rum_metric.go | 399 ++++++++++++++++++ .../internal/utils/api_instances_helper.go | 9 + .../tests/resource_datadog_rum_metric_test.go | 118 ++++++ .../resources/datadog_rum_metric/import.sh | 1 + .../resources/datadog_rum_metric/resource.tf | 20 + .../resources/datadog_rum_metrics/import.sh | 1 + .../resources/datadog_rum_metrics/resource.tf | 20 + 8 files changed, 569 insertions(+) create mode 100644 datadog/fwprovider/resource_datadog_rum_metric.go create mode 100644 datadog/tests/resource_datadog_rum_metric_test.go create mode 100644 examples/resources/datadog_rum_metric/import.sh create mode 100644 examples/resources/datadog_rum_metric/resource.tf create mode 100644 examples/resources/datadog_rum_metrics/import.sh create mode 100644 examples/resources/datadog_rum_metrics/resource.tf diff --git a/datadog/fwprovider/framework_provider.go b/datadog/fwprovider/framework_provider.go index 2c2e7e5ba..85fd3fdc8 100644 --- a/datadog/fwprovider/framework_provider.go +++ b/datadog/fwprovider/framework_provider.go @@ -52,6 +52,7 @@ var Resources = []func() resource.Resource{ NewIpAllowListResource, NewRestrictionPolicyResource, NewRumApplicationResource, + NewRumMetricResource, NewSensitiveDataScannerGroupOrder, NewServiceAccountApplicationKeyResource, NewSpansMetricResource, diff --git a/datadog/fwprovider/resource_datadog_rum_metric.go b/datadog/fwprovider/resource_datadog_rum_metric.go new file mode 100644 index 000000000..df78fab4a --- /dev/null +++ b/datadog/fwprovider/resource_datadog_rum_metric.go @@ -0,0 +1,399 @@ +package fwprovider + +import ( + "context" + + "github.com/DataDog/datadog-api-client-go/v2/api/datadog" + "github.com/DataDog/datadog-api-client-go/v2/api/datadogV2" + "github.com/hashicorp/terraform-plugin-framework/diag" + frameworkPath "github.com/hashicorp/terraform-plugin-framework/path" + "github.com/hashicorp/terraform-plugin-framework/resource" + "github.com/hashicorp/terraform-plugin-framework/resource/schema" + "github.com/hashicorp/terraform-plugin-framework/types" + + "github.com/terraform-providers/terraform-provider-datadog/datadog/internal/utils" +) + +var ( + _ resource.ResourceWithConfigure = &rumMetricResource{} + _ resource.ResourceWithImportState = &rumMetricResource{} +) + +type rumMetricResource struct { + Api *datadogV2.RumMetricsApi + Auth context.Context +} + +type rumMetricModel struct { + ID types.String `tfsdk:"id"` + EventType types.String `tfsdk:"event_type"` + GroupBy []*groupByModel `tfsdk:"group_by"` + Compute *computeModel `tfsdk:"compute"` + Filter *filterModel `tfsdk:"filter"` + Uniqueness *uniquenessModel `tfsdk:"uniqueness"` +} + +type groupByModel struct { + Path types.String `tfsdk:"path"` + TagName types.String `tfsdk:"tag_name"` +} + +type computeModel struct { + AggregationType types.String `tfsdk:"aggregation_type"` + IncludePercentiles types.Bool `tfsdk:"include_percentiles"` + Path types.String `tfsdk:"path"` +} + +type filterModel struct { + Query types.String `tfsdk:"query"` +} + +type uniquenessModel struct { + When types.String `tfsdk:"when"` +} + +func NewRumMetricResource() resource.Resource { + return &rumMetricResource{} +} + +func (r *rumMetricResource) Configure(_ context.Context, request resource.ConfigureRequest, response *resource.ConfigureResponse) { + providerData, _ := request.ProviderData.(*FrameworkProvider) + r.Api = providerData.DatadogApiInstances.GetRumMetricsApiV2() + r.Auth = providerData.Auth +} + +func (r *rumMetricResource) Metadata(_ context.Context, request resource.MetadataRequest, response *resource.MetadataResponse) { + response.TypeName = "rum_metric" +} + +func (r *rumMetricResource) Schema(_ context.Context, _ resource.SchemaRequest, response *resource.SchemaResponse) { + response.Schema = schema.Schema{ + Description: "Provides a Datadog RumMetric resource. This can be used to create and manage Datadog rum_metric.", + Attributes: map[string]schema.Attribute{ + "event_type": schema.StringAttribute{ + Optional: true, + Description: "The type of RUM events to filter on.", + }, + "id": utils.ResourceIDAttribute(), + }, + Blocks: map[string]schema.Block{ + "group_by": schema.ListNestedBlock{ + NestedObject: schema.NestedBlockObject{ + Attributes: map[string]schema.Attribute{ + "path": schema.StringAttribute{ + Optional: true, + Description: "The path to the value the rum-based metric will be aggregated over.", + }, + "tag_name": schema.StringAttribute{ + Optional: true, + Description: "Eventual name of the tag that gets created. By default, `path` is used as the tag name.", + }, + }, + }, + }, + "compute": schema.SingleNestedBlock{ + Attributes: map[string]schema.Attribute{ + "aggregation_type": schema.StringAttribute{ + Optional: true, + Description: "The type of aggregation to use.", + }, + "include_percentiles": schema.BoolAttribute{ + Optional: true, + Description: "Toggle to include or exclude percentile aggregations for distribution metrics. Only present when `aggregation_type` is `distribution`.", + }, + "path": schema.StringAttribute{ + Optional: true, + Description: "The path to the value the rum-based metric will aggregate on. Only present when `aggregation_type` is `distribution`.", + }, + }, + }, + "filter": schema.SingleNestedBlock{ + Attributes: map[string]schema.Attribute{ + "query": schema.StringAttribute{ + Optional: true, + Description: "The search query - following the RUM search syntax.", + }, + }, + }, + "uniqueness": schema.SingleNestedBlock{ + Attributes: map[string]schema.Attribute{ + "when": schema.StringAttribute{ + Optional: true, + Description: "When to count updatable events. `match` when the event is first seen, or `end` when the event is complete.", + }, + }, + }, + }, + } +} + +func (r *rumMetricResource) ImportState(ctx context.Context, request resource.ImportStateRequest, response *resource.ImportStateResponse) { + resource.ImportStatePassthroughID(ctx, frameworkPath.Root("id"), request, response) +} + +func (r *rumMetricResource) Read(ctx context.Context, request resource.ReadRequest, response *resource.ReadResponse) { + var state rumMetricModel + response.Diagnostics.Append(request.State.Get(ctx, &state)...) + if response.Diagnostics.HasError() { + return + } + + id := state.ID.ValueString() + resp, httpResp, err := r.Api.GetRumMetric(r.Auth, id) + if err != nil { + if httpResp != nil && httpResp.StatusCode == 404 { + response.State.RemoveResource(ctx) + return + } + response.Diagnostics.Append(utils.FrameworkErrorDiag(err, "error retrieving RumMetric")) + return + } + if err := utils.CheckForUnparsed(resp); err != nil { + response.Diagnostics.AddError("response contains unparsedObject", err.Error()) + return + } + + r.updateState(ctx, &state, &resp) + + // Save data into Terraform state + response.Diagnostics.Append(response.State.Set(ctx, &state)...) +} + +func (r *rumMetricResource) Create(ctx context.Context, request resource.CreateRequest, response *resource.CreateResponse) { + var state rumMetricModel + response.Diagnostics.Append(request.Plan.Get(ctx, &state)...) + if response.Diagnostics.HasError() { + return + } + + body, diags := r.buildRumMetricRequestBody(ctx, &state) + response.Diagnostics.Append(diags...) + if response.Diagnostics.HasError() { + return + } + + resp, _, err := r.Api.CreateRumMetric(r.Auth, *body) + if err != nil { + response.Diagnostics.Append(utils.FrameworkErrorDiag(err, "error retrieving RumMetric")) + return + } + if err := utils.CheckForUnparsed(resp); err != nil { + response.Diagnostics.AddError("response contains unparsedObject", err.Error()) + return + } + r.updateState(ctx, &state, &resp) + + // Save data into Terraform state + response.Diagnostics.Append(response.State.Set(ctx, &state)...) +} + +func (r *rumMetricResource) Update(ctx context.Context, request resource.UpdateRequest, response *resource.UpdateResponse) { + var state rumMetricModel + response.Diagnostics.Append(request.Plan.Get(ctx, &state)...) + if response.Diagnostics.HasError() { + return + } + + id := state.ID.ValueString() + + body, diags := r.buildRumMetricUpdateRequestBody(ctx, &state) + response.Diagnostics.Append(diags...) + if response.Diagnostics.HasError() { + return + } + + resp, _, err := r.Api.UpdateRumMetric(r.Auth, id, *body) + if err != nil { + response.Diagnostics.Append(utils.FrameworkErrorDiag(err, "error retrieving RumMetric")) + return + } + if err := utils.CheckForUnparsed(resp); err != nil { + response.Diagnostics.AddError("response contains unparsedObject", err.Error()) + return + } + r.updateState(ctx, &state, &resp) + + // Save data into Terraform state + response.Diagnostics.Append(response.State.Set(ctx, &state)...) +} + +func (r *rumMetricResource) Delete(ctx context.Context, request resource.DeleteRequest, response *resource.DeleteResponse) { + var state rumMetricModel + response.Diagnostics.Append(request.State.Get(ctx, &state)...) + if response.Diagnostics.HasError() { + return + } + + id := state.ID.ValueString() + + httpResp, err := r.Api.DeleteRumMetric(r.Auth, id) + if err != nil { + if httpResp != nil && httpResp.StatusCode == 404 { + return + } + response.Diagnostics.Append(utils.FrameworkErrorDiag(err, "error deleting rum_metric")) + return + } +} + +func (r *rumMetricResource) updateState(ctx context.Context, state *rumMetricModel, resp *datadogV2.RumMetricResponse) { + state.ID = types.StringValue(resp.Data.GetId()) + + data := resp.GetData() + attributes := data.GetAttributes() + + state.EventType = types.StringValue(attributes.GetEventType()) + + if groupBy, ok := attributes.GetGroupByOk(); ok && len(*groupBy) > 0 { + state.GroupBy = []*groupByModel{} + for _, groupByDd := range *groupBy { + groupByTfItem := groupByModel{} + + if groupBy, ok := groupByDd.GetGroupByOk(); ok { + + groupByTf := groupByModel{} + if path, ok := groupBy.GetPathOk(); ok { + groupByTf.Path = types.StringValue(*path) + } + if tagName, ok := groupBy.GetTagNameOk(); ok { + groupByTf.TagName = types.StringValue(*tagName) + } + + groupByTfItem.GroupBy = &groupByTf + } + state.GroupBy = append(state.GroupBy, &groupByTfItem) + } + } + + if compute, ok := attributes.GetComputeOk(); ok { + + computeTf := computeModel{} + if aggregationType, ok := compute.GetAggregationTypeOk(); ok { + computeTf.AggregationType = types.StringValue(*aggregationType) + } + if includePercentiles, ok := compute.GetIncludePercentilesOk(); ok { + computeTf.IncludePercentiles = types.BoolValue(*includePercentiles) + } + if path, ok := compute.GetPathOk(); ok { + computeTf.Path = types.StringValue(*path) + } + + state.Compute = &computeTf + } + + if filter, ok := attributes.GetFilterOk(); ok { + + filterTf := filterModel{} + if query, ok := filter.GetQueryOk(); ok { + filterTf.Query = types.StringValue(*query) + } + + state.Filter = &filterTf + } + + if uniqueness, ok := attributes.GetUniquenessOk(); ok { + + uniquenessTf := uniquenessModel{} + if when, ok := uniqueness.GetWhenOk(); ok { + uniquenessTf.When = types.StringValue(*when) + } + + state.Uniqueness = &uniquenessTf + } +} + +func (r *rumMetricResource) buildRumMetricRequestBody(ctx context.Context, state *rumMetricModel) (*datadogV2.RumMetricCreateRequest, diag.Diagnostics) { + diags := diag.Diagnostics{} + attributes := datadogV2.NewRumMetricCreateAttributesWithDefaults() + + attributes.SetEventType(state.EventType.ValueString()) + + if state.GroupBy != nil { + var groupBy []datadogV2.RumMetricGroupBy + for _, groupByTFItem := range state.GroupBy { + groupByDDItem := datadogV2.NewRumMetricGroupBy() + + groupByDDItem.SetPath(groupByTFItem.Path.ValueString()) + if !groupByTFItem.TagName.IsNull() { + groupByDDItem.SetTagName(groupByTFItem.TagName.ValueString()) + } + } + attributes.SetGroupBy(groupBy) + } + + var compute datadogV2.RumMetricCompute + + compute.SetAggregationType(state.Compute.AggregationType.ValueString()) + if !state.Compute.IncludePercentiles.IsNull() { + compute.SetIncludePercentiles(state.Compute.IncludePercentiles.ValueBool()) + } + if !state.Compute.Path.IsNull() { + compute.SetPath(state.Compute.Path.ValueString()) + } + + attributes.Compute = compute + + if state.Filter != nil { + var filter datadogV2.RumMetricFilter + + filter.SetQuery(state.Filter.Query.ValueString()) + + attributes.Filter = &filter + } + + if state.Uniqueness != nil { + var uniqueness datadogV2.RumMetricUniqueness + + uniqueness.SetWhen(state.Uniqueness.When.ValueString()) + + attributes.Uniqueness = &uniqueness + } + + req := datadogV2.NewRumMetricCreateRequestWithDefaults() + req.Data = *datadogV2.NewRumMetricCreateDataWithDefaults() + req.Data.SetAttributes(*attributes) + + return req, diags +} + +func (r *rumMetricResource) buildRumMetricUpdateRequestBody(ctx context.Context, state *rumMetricModel) (*datadogV2.RumMetricUpdateRequest, diag.Diagnostics) { + diags := diag.Diagnostics{} + attributes := datadogV2.NewRumMetricUpdateAttributesWithDefaults() + + if state.GroupBy != nil { + var groupBy []datadogV2.RumMetricGroupBy + for _, groupByTFItem := range state.GroupBy { + groupByDDItem := datadogV2.NewRumMetricGroupBy() + + groupByDDItem.SetPath(groupByTFItem.Path.ValueString()) + if !groupByTFItem.TagName.IsNull() { + groupByDDItem.SetTagName(groupByTFItem.TagName.ValueString()) + } + } + attributes.SetGroupBy(groupBy) + } + + if state.Compute != nil { + var compute datadogV2.RumMetricUpdateCompute + + if !state.Compute.IncludePercentiles.IsNull() { + compute.SetIncludePercentiles(state.Compute.IncludePercentiles.ValueBool()) + } + + attributes.Compute = &compute + } + + if state.Filter != nil { + var filter datadogV2.RumMetricFilter + + filter.SetQuery(state.Filter.Query.ValueString()) + + attributes.Filter = &filter + } + + req := datadogV2.NewRumMetricUpdateRequestWithDefaults() + req.Data = *datadogV2.NewRumMetricUpdateDataWithDefaults() + req.Data.SetAttributes(*attributes) + + return req, diags +} diff --git a/datadog/internal/utils/api_instances_helper.go b/datadog/internal/utils/api_instances_helper.go index fa42a1eb0..91dcc7ab0 100644 --- a/datadog/internal/utils/api_instances_helper.go +++ b/datadog/internal/utils/api_instances_helper.go @@ -75,6 +75,7 @@ type ApiInstances struct { restrictionPolicyApiV2 *datadogV2.RestrictionPoliciesApi rolesApiV2 *datadogV2.RolesApi rumApiV2 *datadogV2.RUMApi + rumMetricsApiV2 *datadogV2.RumMetricsApi securityMonitoringApiV2 *datadogV2.SecurityMonitoringApi sensitiveDataScannerApiV2 *datadogV2.SensitiveDataScannerApi serviceAccountsApiV2 *datadogV2.ServiceAccountsApi @@ -532,6 +533,14 @@ func (i *ApiInstances) GetRumApiV2() *datadogV2.RUMApi { return i.rumApiV2 } +// GetRumApiV2 get instance of RumApi +func (i *ApiInstances) GetRumMetricsApiV2() *datadogV2.RumMetricsApi { + if i.rumMetricsApiV2 == nil { + i.rumMetricsApiV2 = datadogV2.NewRumMetricsApi(i.HttpClient) + } + return i.rumMetricsApiV2 +} + // GetSecurityMonitoringApiV2 get instance of SecurityMonitoringApi func (i *ApiInstances) GetSecurityMonitoringApiV2() *datadogV2.SecurityMonitoringApi { if i.securityMonitoringApiV2 == nil { diff --git a/datadog/tests/resource_datadog_rum_metric_test.go b/datadog/tests/resource_datadog_rum_metric_test.go new file mode 100644 index 000000000..33c20053f --- /dev/null +++ b/datadog/tests/resource_datadog_rum_metric_test.go @@ -0,0 +1,118 @@ +package test + +import ( + "context" + "fmt" + "testing" + + "github.com/hashicorp/terraform-plugin-testing/helper/resource" + "github.com/hashicorp/terraform-plugin-testing/terraform" + + "github.com/terraform-providers/terraform-provider-datadog/datadog" + "github.com/terraform-providers/terraform-provider-datadog/datadog/fwprovider" + "github.com/terraform-providers/terraform-provider-datadog/datadog/internal/utils" +) + +func TestAccRumMetricBasic(t *testing.T) { + t.Parallel() + ctx, providers, accProviders := testAccFrameworkMuxProviders(context.Background(), t) + uniq := uniqueEntityName(ctx, t) + + resource.Test(t, resource.TestCase{ + ProtoV5ProviderFactories: accProviders, + CheckDestroy: testAccCheckDatadogRumMetricDestroy(providers.frameworkProvider), + Steps: []resource.TestStep{ + { + Config: testAccCheckDatadogRumMetric(uniq), + Check: resource.ComposeTestCheckFunc( + testAccCheckDatadogRumMetricExists(providers.frameworkProvider), + resource.TestCheckResourceAttr( + "datadog_rum_metric.foo", "event_type", "session"), + ), + }, + }, + }) +} + +func testAccCheckDatadogRumMetric(uniq string) string { + // Update me to make use of the unique value + return fmt.Sprintf(`resource "datadog_rum_metric" "foo" { + compute { + aggregation_type = "distribution" + include_percentiles = True + path = "@duration" + } + event_type = "session" + filter { + query = "@service:web-ui: " + } + group_by { + path = "@browser.name" + tag_name = "browser_name" + } + uniqueness { + when = "match" + } +}`, uniq) +} + +func testAccCheckDatadogRumMetricDestroy(accProvider *fwprovider.FrameworkProvider) func(*terraform.State) error { + return func(s *terraform.State) error { + apiInstances := accProvider.DatadogApiInstances + auth := accProvider.Auth + + if err := RumMetricDestroyHelper(auth, s, apiInstances); err != nil { + return err + } + return nil + } +} + +func RumMetricDestroyHelper(auth context.Context, s *terraform.State, apiInstances *utils.ApiInstances) error { + err := utils.Retry(2, 10, func() error { + for _, r := range s.RootModule().Resources { + if r.Type != "resource_datadog_rum_metric" { + continue + } + id := r.Primary.ID + + _, httpResp, err := apiInstances.GetRumMetricsApiV2().GetRumMetric(auth, id) + if err != nil { + if httpResp != nil && httpResp.StatusCode == 404 { + return nil + } + return &utils.RetryableError{Prob: fmt.Sprintf("received an error retrieving RumMetric %s", err)} + } + return &utils.RetryableError{Prob: "RumMetric still exists"} + } + return nil + }) + return err +} + +func testAccCheckDatadogRumMetricExists(accProvider *fwprovider.FrameworkProvider) resource.TestCheckFunc { + return func(s *terraform.State) error { + apiInstances := accProvider.DatadogApiInstances + auth := accProvider.Auth + + if err := rumMetricExistsHelper(auth, s, apiInstances); err != nil { + return err + } + return nil + } +} + +func rumMetricExistsHelper(auth context.Context, s *terraform.State, apiInstances *utils.ApiInstances) error { + for _, r := range s.RootModule().Resources { + if r.Type != "resource_datadog_rum_metric" { + continue + } + id := r.Primary.ID + + _, httpResp, err := apiInstances.GetRumMetricsApiV2().GetRumMetric(auth, id) + if err != nil { + return utils.TranslateClientError(err, httpResp, "error retrieving RumMetric") + } + } + return nil +} diff --git a/examples/resources/datadog_rum_metric/import.sh b/examples/resources/datadog_rum_metric/import.sh new file mode 100644 index 000000000..43d00dbfc --- /dev/null +++ b/examples/resources/datadog_rum_metric/import.sh @@ -0,0 +1 @@ +terraform import datadog_rum_metric.new_list "" \ No newline at end of file diff --git a/examples/resources/datadog_rum_metric/resource.tf b/examples/resources/datadog_rum_metric/resource.tf new file mode 100644 index 000000000..bd7c48ebd --- /dev/null +++ b/examples/resources/datadog_rum_metric/resource.tf @@ -0,0 +1,20 @@ +# Create new rum_metric resource + +resource "datadog_rum_metric" "foo" { + compute { + aggregation_type = "distribution" + include_percentiles = True + path = "@duration" + } + event_type = "session" + filter { + query = "@service:web-ui: " + } + group_by { + path = "@browser.name" + tag_name = "browser_name" + } + uniqueness { + when = "match" + } +} \ No newline at end of file diff --git a/examples/resources/datadog_rum_metrics/import.sh b/examples/resources/datadog_rum_metrics/import.sh new file mode 100644 index 000000000..d3aadea1b --- /dev/null +++ b/examples/resources/datadog_rum_metrics/import.sh @@ -0,0 +1 @@ +terraform import datadog_rum_metrics.new_list "" \ No newline at end of file diff --git a/examples/resources/datadog_rum_metrics/resource.tf b/examples/resources/datadog_rum_metrics/resource.tf new file mode 100644 index 000000000..2fc54d628 --- /dev/null +++ b/examples/resources/datadog_rum_metrics/resource.tf @@ -0,0 +1,20 @@ +# Create new rum_metrics resource + +resource "datadog_rum_metrics" "foo" { + compute { + aggregation_type = "distribution" + include_percentiles = True + path = "@duration" + } + event_type = "session" + filter { + query = "@service:web-ui: " + } + group_by { + path = "@browser.name" + tag_name = "browser_name" + } + uniqueness { + when = "match" + } +} \ No newline at end of file From 728ac625734731a874baeec3567500b320112719 Mon Sep 17 00:00:00 2001 From: Arthur Hemery Date: Wed, 6 Nov 2024 19:47:02 +0100 Subject: [PATCH 02/10] Some fixes on the boilerplate --- .../fwprovider/resource_datadog_rum_metric.go | 74 +++++++++---------- 1 file changed, 33 insertions(+), 41 deletions(-) diff --git a/datadog/fwprovider/resource_datadog_rum_metric.go b/datadog/fwprovider/resource_datadog_rum_metric.go index df78fab4a..790238538 100644 --- a/datadog/fwprovider/resource_datadog_rum_metric.go +++ b/datadog/fwprovider/resource_datadog_rum_metric.go @@ -3,7 +3,6 @@ package fwprovider import ( "context" - "github.com/DataDog/datadog-api-client-go/v2/api/datadog" "github.com/DataDog/datadog-api-client-go/v2/api/datadogV2" "github.com/hashicorp/terraform-plugin-framework/diag" frameworkPath "github.com/hashicorp/terraform-plugin-framework/path" @@ -25,30 +24,30 @@ type rumMetricResource struct { } type rumMetricModel struct { - ID types.String `tfsdk:"id"` - EventType types.String `tfsdk:"event_type"` - GroupBy []*groupByModel `tfsdk:"group_by"` - Compute *computeModel `tfsdk:"compute"` - Filter *filterModel `tfsdk:"filter"` - Uniqueness *uniquenessModel `tfsdk:"uniqueness"` + ID types.String `tfsdk:"id"` + EventType types.String `tfsdk:"event_type"` + GroupBy []*rumMetricGroupByModel `tfsdk:"group_by"` + Compute *rumMetricComputeModel `tfsdk:"compute"` + Filter *rumMetricFilterModel `tfsdk:"filter"` + Uniqueness *rumMetricUniquenessModel `tfsdk:"uniqueness"` } -type groupByModel struct { +type rumMetricGroupByModel struct { Path types.String `tfsdk:"path"` TagName types.String `tfsdk:"tag_name"` } -type computeModel struct { +type rumMetricComputeModel struct { AggregationType types.String `tfsdk:"aggregation_type"` IncludePercentiles types.Bool `tfsdk:"include_percentiles"` Path types.String `tfsdk:"path"` } -type filterModel struct { +type rumMetricFilterModel struct { Query types.String `tfsdk:"query"` } -type uniquenessModel struct { +type rumMetricUniquenessModel struct { When types.String `tfsdk:"when"` } @@ -71,8 +70,8 @@ func (r *rumMetricResource) Schema(_ context.Context, _ resource.SchemaRequest, Description: "Provides a Datadog RumMetric resource. This can be used to create and manage Datadog rum_metric.", Attributes: map[string]schema.Attribute{ "event_type": schema.StringAttribute{ - Optional: true, Description: "The type of RUM events to filter on.", + Required: true, }, "id": utils.ResourceIDAttribute(), }, @@ -81,8 +80,8 @@ func (r *rumMetricResource) Schema(_ context.Context, _ resource.SchemaRequest, NestedObject: schema.NestedBlockObject{ Attributes: map[string]schema.Attribute{ "path": schema.StringAttribute{ - Optional: true, Description: "The path to the value the rum-based metric will be aggregated over.", + Optional: true, }, "tag_name": schema.StringAttribute{ Optional: true, @@ -94,7 +93,7 @@ func (r *rumMetricResource) Schema(_ context.Context, _ resource.SchemaRequest, "compute": schema.SingleNestedBlock{ Attributes: map[string]schema.Attribute{ "aggregation_type": schema.StringAttribute{ - Optional: true, + Required: true, Description: "The type of aggregation to use.", }, "include_percentiles": schema.BoolAttribute{ @@ -242,34 +241,29 @@ func (r *rumMetricResource) updateState(ctx context.Context, state *rumMetricMod data := resp.GetData() attributes := data.GetAttributes() - state.EventType = types.StringValue(attributes.GetEventType()) + state.EventType = types.StringValue(string(attributes.GetEventType())) if groupBy, ok := attributes.GetGroupByOk(); ok && len(*groupBy) > 0 { - state.GroupBy = []*groupByModel{} - for _, groupByDd := range *groupBy { - groupByTfItem := groupByModel{} - - if groupBy, ok := groupByDd.GetGroupByOk(); ok { + state.GroupBy = []*rumMetricGroupByModel{} + for _, groupByDdItem := range *groupBy { + groupByTfItem := rumMetricGroupByModel{} - groupByTf := groupByModel{} - if path, ok := groupBy.GetPathOk(); ok { - groupByTf.Path = types.StringValue(*path) - } - if tagName, ok := groupBy.GetTagNameOk(); ok { - groupByTf.TagName = types.StringValue(*tagName) - } - - groupByTfItem.GroupBy = &groupByTf + if path, ok := groupByDdItem.GetPathOk(); ok { + groupByTfItem.Path = types.StringValue(*path) + } + if tagName, ok := groupByDdItem.GetTagNameOk(); ok { + groupByTfItem.TagName = types.StringValue(*tagName) } + state.GroupBy = append(state.GroupBy, &groupByTfItem) } } if compute, ok := attributes.GetComputeOk(); ok { - computeTf := computeModel{} + computeTf := rumMetricComputeModel{} if aggregationType, ok := compute.GetAggregationTypeOk(); ok { - computeTf.AggregationType = types.StringValue(*aggregationType) + computeTf.AggregationType = types.StringValue(string(*aggregationType)) } if includePercentiles, ok := compute.GetIncludePercentilesOk(); ok { computeTf.IncludePercentiles = types.BoolValue(*includePercentiles) @@ -283,7 +277,7 @@ func (r *rumMetricResource) updateState(ctx context.Context, state *rumMetricMod if filter, ok := attributes.GetFilterOk(); ok { - filterTf := filterModel{} + filterTf := rumMetricFilterModel{} if query, ok := filter.GetQueryOk(); ok { filterTf.Query = types.StringValue(*query) } @@ -293,9 +287,9 @@ func (r *rumMetricResource) updateState(ctx context.Context, state *rumMetricMod if uniqueness, ok := attributes.GetUniquenessOk(); ok { - uniquenessTf := uniquenessModel{} + uniquenessTf := rumMetricUniquenessModel{} if when, ok := uniqueness.GetWhenOk(); ok { - uniquenessTf.When = types.StringValue(*when) + uniquenessTf.When = types.StringValue(string(*when)) } state.Uniqueness = &uniquenessTf @@ -306,14 +300,13 @@ func (r *rumMetricResource) buildRumMetricRequestBody(ctx context.Context, state diags := diag.Diagnostics{} attributes := datadogV2.NewRumMetricCreateAttributesWithDefaults() - attributes.SetEventType(state.EventType.ValueString()) + attributes.SetEventType(datadogV2.RumMetricEventType(state.EventType.ValueString())) if state.GroupBy != nil { var groupBy []datadogV2.RumMetricGroupBy for _, groupByTFItem := range state.GroupBy { - groupByDDItem := datadogV2.NewRumMetricGroupBy() + groupByDDItem := datadogV2.NewRumMetricGroupBy(groupByTFItem.Path.ValueString()) - groupByDDItem.SetPath(groupByTFItem.Path.ValueString()) if !groupByTFItem.TagName.IsNull() { groupByDDItem.SetTagName(groupByTFItem.TagName.ValueString()) } @@ -323,7 +316,7 @@ func (r *rumMetricResource) buildRumMetricRequestBody(ctx context.Context, state var compute datadogV2.RumMetricCompute - compute.SetAggregationType(state.Compute.AggregationType.ValueString()) + compute.SetAggregationType(datadogV2.RumMetricComputeAggregationType(state.Compute.AggregationType.ValueString())) if !state.Compute.IncludePercentiles.IsNull() { compute.SetIncludePercentiles(state.Compute.IncludePercentiles.ValueBool()) } @@ -344,7 +337,7 @@ func (r *rumMetricResource) buildRumMetricRequestBody(ctx context.Context, state if state.Uniqueness != nil { var uniqueness datadogV2.RumMetricUniqueness - uniqueness.SetWhen(state.Uniqueness.When.ValueString()) + uniqueness.SetWhen(datadogV2.RumMetricUniquenessWhen(state.Uniqueness.When.ValueString())) attributes.Uniqueness = &uniqueness } @@ -363,9 +356,8 @@ func (r *rumMetricResource) buildRumMetricUpdateRequestBody(ctx context.Context, if state.GroupBy != nil { var groupBy []datadogV2.RumMetricGroupBy for _, groupByTFItem := range state.GroupBy { - groupByDDItem := datadogV2.NewRumMetricGroupBy() + groupByDDItem := datadogV2.NewRumMetricGroupBy(groupByTFItem.Path.ValueString()) - groupByDDItem.SetPath(groupByTFItem.Path.ValueString()) if !groupByTFItem.TagName.IsNull() { groupByDDItem.SetTagName(groupByTFItem.TagName.ValueString()) } From 369113ca00df654788dd9938513ea40f6ff01b43 Mon Sep 17 00:00:00 2001 From: Arthur Hemery Date: Thu, 7 Nov 2024 22:46:05 +0100 Subject: [PATCH 03/10] Tests + fixes --- .../fwprovider/resource_datadog_rum_metric.go | 39 +++++-- datadog/tests/provider_test.go | 1 + .../tests/resource_datadog_rum_metric_test.go | 88 +++++++++++---- docs/resources/rum_metric.md | 100 ++++++++++++++++++ 4 files changed, 199 insertions(+), 29 deletions(-) create mode 100644 docs/resources/rum_metric.md diff --git a/datadog/fwprovider/resource_datadog_rum_metric.go b/datadog/fwprovider/resource_datadog_rum_metric.go index 790238538..49e61f8ab 100644 --- a/datadog/fwprovider/resource_datadog_rum_metric.go +++ b/datadog/fwprovider/resource_datadog_rum_metric.go @@ -8,6 +8,8 @@ import ( frameworkPath "github.com/hashicorp/terraform-plugin-framework/path" "github.com/hashicorp/terraform-plugin-framework/resource" "github.com/hashicorp/terraform-plugin-framework/resource/schema" + "github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier" + "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringplanmodifier" "github.com/hashicorp/terraform-plugin-framework/types" "github.com/terraform-providers/terraform-provider-datadog/datadog/internal/utils" @@ -25,6 +27,7 @@ type rumMetricResource struct { type rumMetricModel struct { ID types.String `tfsdk:"id"` + Name types.String `tfsdk:"name"` EventType types.String `tfsdk:"event_type"` GroupBy []*rumMetricGroupByModel `tfsdk:"group_by"` Compute *rumMetricComputeModel `tfsdk:"compute"` @@ -69,9 +72,19 @@ func (r *rumMetricResource) Schema(_ context.Context, _ resource.SchemaRequest, response.Schema = schema.Schema{ Description: "Provides a Datadog RumMetric resource. This can be used to create and manage Datadog rum_metric.", Attributes: map[string]schema.Attribute{ + "name": schema.StringAttribute{ + Description: "The name of the rum-based metric. This field can't be updated after creation.", + Required: true, + PlanModifiers: []planmodifier.String{ + stringplanmodifier.RequiresReplace(), + }, + }, "event_type": schema.StringAttribute{ Description: "The type of RUM events to filter on.", Required: true, + PlanModifiers: []planmodifier.String{ + stringplanmodifier.RequiresReplace(), + }, }, "id": utils.ResourceIDAttribute(), }, @@ -84,8 +97,8 @@ func (r *rumMetricResource) Schema(_ context.Context, _ resource.SchemaRequest, Optional: true, }, "tag_name": schema.StringAttribute{ - Optional: true, Description: "Eventual name of the tag that gets created. By default, `path` is used as the tag name.", + Optional: true, }, }, }, @@ -93,32 +106,38 @@ func (r *rumMetricResource) Schema(_ context.Context, _ resource.SchemaRequest, "compute": schema.SingleNestedBlock{ Attributes: map[string]schema.Attribute{ "aggregation_type": schema.StringAttribute{ - Required: true, Description: "The type of aggregation to use.", + Required: true, + PlanModifiers: []planmodifier.String{ + stringplanmodifier.RequiresReplace(), + }, }, "include_percentiles": schema.BoolAttribute{ - Optional: true, Description: "Toggle to include or exclude percentile aggregations for distribution metrics. Only present when `aggregation_type` is `distribution`.", + Optional: true, }, "path": schema.StringAttribute{ - Optional: true, Description: "The path to the value the rum-based metric will aggregate on. Only present when `aggregation_type` is `distribution`.", + Optional: true, }, }, }, "filter": schema.SingleNestedBlock{ Attributes: map[string]schema.Attribute{ "query": schema.StringAttribute{ - Optional: true, Description: "The search query - following the RUM search syntax.", + Optional: true, }, }, }, "uniqueness": schema.SingleNestedBlock{ Attributes: map[string]schema.Attribute{ "when": schema.StringAttribute{ - Optional: true, Description: "When to count updatable events. `match` when the event is first seen, or `end` when the event is complete.", + Optional: true, + PlanModifiers: []planmodifier.String{ + stringplanmodifier.RequiresReplace(), + }, }, }, }, @@ -237,6 +256,7 @@ func (r *rumMetricResource) Delete(ctx context.Context, request resource.DeleteR func (r *rumMetricResource) updateState(ctx context.Context, state *rumMetricModel, resp *datadogV2.RumMetricResponse) { state.ID = types.StringValue(resp.Data.GetId()) + state.Name = types.StringValue(resp.Data.GetId()) data := resp.GetData() attributes := data.GetAttributes() @@ -269,7 +289,9 @@ func (r *rumMetricResource) updateState(ctx context.Context, state *rumMetricMod computeTf.IncludePercentiles = types.BoolValue(*includePercentiles) } if path, ok := compute.GetPathOk(); ok { - computeTf.Path = types.StringValue(*path) + if *path != "" { + computeTf.Path = types.StringValue(*path) + } } state.Compute = &computeTf @@ -310,6 +332,7 @@ func (r *rumMetricResource) buildRumMetricRequestBody(ctx context.Context, state if !groupByTFItem.TagName.IsNull() { groupByDDItem.SetTagName(groupByTFItem.TagName.ValueString()) } + groupBy = append(groupBy, *groupByDDItem) } attributes.SetGroupBy(groupBy) } @@ -344,6 +367,7 @@ func (r *rumMetricResource) buildRumMetricRequestBody(ctx context.Context, state req := datadogV2.NewRumMetricCreateRequestWithDefaults() req.Data = *datadogV2.NewRumMetricCreateDataWithDefaults() + req.Data.SetId(state.Name.String()) req.Data.SetAttributes(*attributes) return req, diags @@ -385,6 +409,7 @@ func (r *rumMetricResource) buildRumMetricUpdateRequestBody(ctx context.Context, req := datadogV2.NewRumMetricUpdateRequestWithDefaults() req.Data = *datadogV2.NewRumMetricUpdateDataWithDefaults() + req.Data.SetId(state.Name.String()) req.Data.SetAttributes(*attributes) return req, diags diff --git a/datadog/tests/provider_test.go b/datadog/tests/provider_test.go index 8407fb8b8..5cf227a2e 100644 --- a/datadog/tests/provider_test.go +++ b/datadog/tests/provider_test.go @@ -213,6 +213,7 @@ var testFiles2EndpointTags = map[string]string{ "tests/resource_datadog_restriction_policy_test": "restriction-policy", "tests/resource_datadog_role_test": "roles", "tests/resource_datadog_rum_application_test": "rum-application", + "tests/resource_datadog_rum_metric_test": "rum-metric", "tests/resource_datadog_screenboard_test": "dashboards", "tests/resource_datadog_security_monitoring_default_rule_test": "security-monitoring", "tests/resource_datadog_security_monitoring_filter_test": "security-monitoring", diff --git a/datadog/tests/resource_datadog_rum_metric_test.go b/datadog/tests/resource_datadog_rum_metric_test.go index 33c20053f..a6f6083af 100644 --- a/datadog/tests/resource_datadog_rum_metric_test.go +++ b/datadog/tests/resource_datadog_rum_metric_test.go @@ -3,20 +3,43 @@ package test import ( "context" "fmt" + "strings" "testing" "github.com/hashicorp/terraform-plugin-testing/helper/resource" "github.com/hashicorp/terraform-plugin-testing/terraform" - "github.com/terraform-providers/terraform-provider-datadog/datadog" "github.com/terraform-providers/terraform-provider-datadog/datadog/fwprovider" "github.com/terraform-providers/terraform-provider-datadog/datadog/internal/utils" ) +func TestAccRumMetric_import(t *testing.T) { + t.Parallel() + resourceName := "datadog_rum_metric.testing_rum_metric" + ctx, providers, accProviders := testAccFrameworkMuxProviders(context.Background(), t) + uniq := strings.ReplaceAll(uniqueEntityName(ctx, t), "-", "_") + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + ProtoV5ProviderFactories: accProviders, + CheckDestroy: testAccCheckDatadogRumMetricDestroy(providers.frameworkProvider), + Steps: []resource.TestStep{ + { + Config: testAccCheckDatadogRumMetric(uniq), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + func TestAccRumMetricBasic(t *testing.T) { t.Parallel() ctx, providers, accProviders := testAccFrameworkMuxProviders(context.Background(), t) - uniq := uniqueEntityName(ctx, t) + uniq := strings.ReplaceAll(uniqueEntityName(ctx, t), "-", "_") resource.Test(t, resource.TestCase{ ProtoV5ProviderFactories: accProviders, @@ -27,7 +50,27 @@ func TestAccRumMetricBasic(t *testing.T) { Check: resource.ComposeTestCheckFunc( testAccCheckDatadogRumMetricExists(providers.frameworkProvider), resource.TestCheckResourceAttr( - "datadog_rum_metric.foo", "event_type", "session"), + "datadog_rum_metric.testing_rum_metric", "id", uniq), + resource.TestCheckResourceAttr( + "datadog_rum_metric.testing_rum_metric", "name", uniq), + resource.TestCheckResourceAttr( + "datadog_rum_metric.testing_rum_metric", "event_type", "session"), + resource.TestCheckResourceAttr( + "datadog_rum_metric.testing_rum_metric", "compute.aggregation_type", "distribution"), + resource.TestCheckResourceAttr( + "datadog_rum_metric.testing_rum_metric", "compute.include_percentiles", "true"), + resource.TestCheckResourceAttr( + "datadog_rum_metric.testing_rum_metric", "compute.path", "@duration"), + resource.TestCheckResourceAttr( + "datadog_rum_metric.testing_rum_metric", "filter.query", "@service:web-ui"), + resource.TestCheckResourceAttr( + "datadog_rum_metric.testing_rum_metric", "group_by.#", "1"), + resource.TestCheckResourceAttr( + "datadog_rum_metric.testing_rum_metric", "group_by.0.path", "@browser.name"), + resource.TestCheckResourceAttr( + "datadog_rum_metric.testing_rum_metric", "group_by.0.tag_name", "browser_name"), + resource.TestCheckResourceAttr( + "datadog_rum_metric.testing_rum_metric", "uniqueness.when", "match"), ), }, }, @@ -35,25 +78,26 @@ func TestAccRumMetricBasic(t *testing.T) { } func testAccCheckDatadogRumMetric(uniq string) string { - // Update me to make use of the unique value - return fmt.Sprintf(`resource "datadog_rum_metric" "foo" { - compute { - aggregation_type = "distribution" - include_percentiles = True - path = "@duration" - } - event_type = "session" - filter { - query = "@service:web-ui: " - } - group_by { - path = "@browser.name" - tag_name = "browser_name" - } - uniqueness { - when = "match" - } -}`, uniq) + return fmt.Sprintf(`resource "datadog_rum_metric" "testing_rum_metric" { + name = %q + event_type = "session" + compute { + aggregation_type = "distribution" + include_percentiles = true + path = "@duration" + } + filter { + query = "@service:web-ui" + } + group_by { + path = "@browser.name" + tag_name = "browser_name" + } + uniqueness { + when = "match" + } + } + `, uniq) } func testAccCheckDatadogRumMetricDestroy(accProvider *fwprovider.FrameworkProvider) func(*terraform.State) error { diff --git a/docs/resources/rum_metric.md b/docs/resources/rum_metric.md new file mode 100644 index 000000000..1e9c181bf --- /dev/null +++ b/docs/resources/rum_metric.md @@ -0,0 +1,100 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "datadog_rum_metric Resource - terraform-provider-datadog" +subcategory: "" +description: |- + Provides a Datadog RumMetric resource. This can be used to create and manage Datadog rum_metric. +--- + +# datadog_rum_metric (Resource) + +Provides a Datadog RumMetric resource. This can be used to create and manage Datadog rum_metric. + +## Example Usage + +```terraform +# Create new rum_metric resource + +resource "datadog_rum_metric" "foo" { + compute { + aggregation_type = "distribution" + include_percentiles = True + path = "@duration" + } + event_type = "session" + filter { + query = "@service:web-ui: " + } + group_by { + path = "@browser.name" + tag_name = "browser_name" + } + uniqueness { + when = "match" + } +} +``` + + +## Schema + +### Required + +- `event_type` (String) The type of RUM events to filter on. +- `name` (String) The name of the rum-based metric. This field can't be updated after creation. + +### Optional + +- `compute` (Block, Optional) (see [below for nested schema](#nestedblock--compute)) +- `filter` (Block, Optional) (see [below for nested schema](#nestedblock--filter)) +- `group_by` (Block List) (see [below for nested schema](#nestedblock--group_by)) +- `uniqueness` (Block, Optional) (see [below for nested schema](#nestedblock--uniqueness)) + +### Read-Only + +- `id` (String) The ID of this resource. + + +### Nested Schema for `compute` + +Required: + +- `aggregation_type` (String) The type of aggregation to use. + +Optional: + +- `include_percentiles` (Boolean) Toggle to include or exclude percentile aggregations for distribution metrics. Only present when `aggregation_type` is `distribution`. +- `path` (String) The path to the value the rum-based metric will aggregate on. Only present when `aggregation_type` is `distribution`. + + + +### Nested Schema for `filter` + +Optional: + +- `query` (String) The search query - following the RUM search syntax. + + + +### Nested Schema for `group_by` + +Optional: + +- `path` (String) The path to the value the rum-based metric will be aggregated over. +- `tag_name` (String) Eventual name of the tag that gets created. By default, `path` is used as the tag name. + + + +### Nested Schema for `uniqueness` + +Optional: + +- `when` (String) When to count updatable events. `match` when the event is first seen, or `end` when the event is complete. + +## Import + +Import is supported using the following syntax: + +```shell +terraform import datadog_rum_metric.new_list "" +``` From e2ab82eab3603b9e227661c38cbbb43a9c82e83a Mon Sep 17 00:00:00 2001 From: Arthur Hemery Date: Fri, 8 Nov 2024 14:19:21 +0100 Subject: [PATCH 04/10] Working base version --- .../fwprovider/resource_datadog_rum_metric.go | 31 ++-- .../tests/resource_datadog_rum_metric_test.go | 133 +++++++++++++++--- 2 files changed, 127 insertions(+), 37 deletions(-) diff --git a/datadog/fwprovider/resource_datadog_rum_metric.go b/datadog/fwprovider/resource_datadog_rum_metric.go index 49e61f8ab..0fe327924 100644 --- a/datadog/fwprovider/resource_datadog_rum_metric.go +++ b/datadog/fwprovider/resource_datadog_rum_metric.go @@ -89,20 +89,6 @@ func (r *rumMetricResource) Schema(_ context.Context, _ resource.SchemaRequest, "id": utils.ResourceIDAttribute(), }, Blocks: map[string]schema.Block{ - "group_by": schema.ListNestedBlock{ - NestedObject: schema.NestedBlockObject{ - Attributes: map[string]schema.Attribute{ - "path": schema.StringAttribute{ - Description: "The path to the value the rum-based metric will be aggregated over.", - Optional: true, - }, - "tag_name": schema.StringAttribute{ - Description: "Eventual name of the tag that gets created. By default, `path` is used as the tag name.", - Optional: true, - }, - }, - }, - }, "compute": schema.SingleNestedBlock{ Attributes: map[string]schema.Attribute{ "aggregation_type": schema.StringAttribute{ @@ -130,6 +116,20 @@ func (r *rumMetricResource) Schema(_ context.Context, _ resource.SchemaRequest, }, }, }, + "group_by": schema.SetNestedBlock{ + NestedObject: schema.NestedBlockObject{ + Attributes: map[string]schema.Attribute{ + "path": schema.StringAttribute{ + Description: "The path to the value the rum-based metric will be aggregated over.", + Optional: true, + }, + "tag_name": schema.StringAttribute{ + Description: "Eventual name of the tag that gets created. By default, `path` is used as the tag name.", + Optional: true, + }, + }, + }, + }, "uniqueness": schema.SingleNestedBlock{ Attributes: map[string]schema.Attribute{ "when": schema.StringAttribute{ @@ -267,7 +267,6 @@ func (r *rumMetricResource) updateState(ctx context.Context, state *rumMetricMod state.GroupBy = []*rumMetricGroupByModel{} for _, groupByDdItem := range *groupBy { groupByTfItem := rumMetricGroupByModel{} - if path, ok := groupByDdItem.GetPathOk(); ok { groupByTfItem.Path = types.StringValue(*path) } @@ -385,6 +384,8 @@ func (r *rumMetricResource) buildRumMetricUpdateRequestBody(ctx context.Context, if !groupByTFItem.TagName.IsNull() { groupByDDItem.SetTagName(groupByTFItem.TagName.ValueString()) } + + groupBy = append(groupBy, *groupByDDItem) } attributes.SetGroupBy(groupBy) } diff --git a/datadog/tests/resource_datadog_rum_metric_test.go b/datadog/tests/resource_datadog_rum_metric_test.go index a6f6083af..4f3756aa9 100644 --- a/datadog/tests/resource_datadog_rum_metric_test.go +++ b/datadog/tests/resource_datadog_rum_metric_test.go @@ -13,10 +13,16 @@ import ( "github.com/terraform-providers/terraform-provider-datadog/datadog/internal/utils" ) -func TestAccRumMetric_import(t *testing.T) { +func TestAccRumMetricImport(t *testing.T) { t.Parallel() resourceName := "datadog_rum_metric.testing_rum_metric" ctx, providers, accProviders := testAccFrameworkMuxProviders(context.Background(), t) + + // The API will currently silently remap - to _, which makes terraform unhappy. This will + // just make the tests pass but this is a real issue. + // Being addressed in https://datadoghq.atlassian.net/browse/RUM-7124. Note that this is + // also an issue for other existing APIs using the same backend (spans metrics and maybe + // logs metrics?). uniq := strings.ReplaceAll(uniqueEntityName(ctx, t), "-", "_") resource.Test(t, resource.TestCase{ @@ -25,7 +31,7 @@ func TestAccRumMetric_import(t *testing.T) { CheckDestroy: testAccCheckDatadogRumMetricDestroy(providers.frameworkProvider), Steps: []resource.TestStep{ { - Config: testAccCheckDatadogRumMetric(uniq), + Config: minimalDatadogRumMetric(uniq), }, { ResourceName: resourceName, @@ -36,7 +42,7 @@ func TestAccRumMetric_import(t *testing.T) { }) } -func TestAccRumMetricBasic(t *testing.T) { +func TestAccRumMetricAttributes(t *testing.T) { t.Parallel() ctx, providers, accProviders := testAccFrameworkMuxProviders(context.Background(), t) uniq := strings.ReplaceAll(uniqueEntityName(ctx, t), "-", "_") @@ -46,7 +52,7 @@ func TestAccRumMetricBasic(t *testing.T) { CheckDestroy: testAccCheckDatadogRumMetricDestroy(providers.frameworkProvider), Steps: []resource.TestStep{ { - Config: testAccCheckDatadogRumMetric(uniq), + Config: minimalDatadogRumMetric(uniq), Check: resource.ComposeTestCheckFunc( testAccCheckDatadogRumMetricExists(providers.frameworkProvider), resource.TestCheckResourceAttr( @@ -54,48 +60,131 @@ func TestAccRumMetricBasic(t *testing.T) { resource.TestCheckResourceAttr( "datadog_rum_metric.testing_rum_metric", "name", uniq), resource.TestCheckResourceAttr( - "datadog_rum_metric.testing_rum_metric", "event_type", "session"), + "datadog_rum_metric.testing_rum_metric", "event_type", "action"), + resource.TestCheckResourceAttr( + "datadog_rum_metric.testing_rum_metric", "compute.aggregation_type", "count"), + ), + }, + }, + }) + + resource.Test(t, resource.TestCase{ + ProtoV5ProviderFactories: accProviders, + CheckDestroy: testAccCheckDatadogRumMetricDestroy(providers.frameworkProvider), + Steps: []resource.TestStep{ + { + Config: distributionDatadogRumMetric(uniq), + Check: resource.ComposeTestCheckFunc( + testAccCheckDatadogRumMetricExists(providers.frameworkProvider), resource.TestCheckResourceAttr( "datadog_rum_metric.testing_rum_metric", "compute.aggregation_type", "distribution"), resource.TestCheckResourceAttr( "datadog_rum_metric.testing_rum_metric", "compute.include_percentiles", "true"), resource.TestCheckResourceAttr( "datadog_rum_metric.testing_rum_metric", "compute.path", "@duration"), + ), + }, + }, + }) + + resource.Test(t, resource.TestCase{ + ProtoV5ProviderFactories: accProviders, + CheckDestroy: testAccCheckDatadogRumMetricDestroy(providers.frameworkProvider), + Steps: []resource.TestStep{ + { + Config: filterDatadogRumMetric(uniq), + Check: resource.ComposeTestCheckFunc( + testAccCheckDatadogRumMetricExists(providers.frameworkProvider), resource.TestCheckResourceAttr( "datadog_rum_metric.testing_rum_metric", "filter.query", "@service:web-ui"), - resource.TestCheckResourceAttr( - "datadog_rum_metric.testing_rum_metric", "group_by.#", "1"), - resource.TestCheckResourceAttr( - "datadog_rum_metric.testing_rum_metric", "group_by.0.path", "@browser.name"), - resource.TestCheckResourceAttr( - "datadog_rum_metric.testing_rum_metric", "group_by.0.tag_name", "browser_name"), - resource.TestCheckResourceAttr( - "datadog_rum_metric.testing_rum_metric", "uniqueness.when", "match"), ), }, }, }) + + resource.Test(t, resource.TestCase{ + ProtoV5ProviderFactories: accProviders, + CheckDestroy: testAccCheckDatadogRumMetricDestroy(providers.frameworkProvider), + Steps: []resource.TestStep{ + { + Config: groupByDatadogRumMetric(uniq), + Check: testAccCheckDatadogRumMetricExists(providers.frameworkProvider), + // resource.ComposeTestCheckFunc( + + // resource.TestCheckResourceAttr( + // "datadog_rum_metric.testing_rum_metric", "group_by.#", "2"), + // ), + }, + }, + }) +} + +func minimalDatadogRumMetric(uniq string) string { + return fmt.Sprintf(`resource "datadog_rum_metric" "testing_rum_metric" { + name = %q + event_type = "action" + compute { + aggregation_type = "count" + } + } + `, uniq) } -func testAccCheckDatadogRumMetric(uniq string) string { +func distributionDatadogRumMetric(uniq string) string { return fmt.Sprintf(`resource "datadog_rum_metric" "testing_rum_metric" { name = %q - event_type = "session" + event_type = "action" compute { aggregation_type = "distribution" include_percentiles = true path = "@duration" } - filter { - query = "@service:web-ui" + } + `, uniq) +} + +func countDatadogRumMetric(uniq string) string { + return fmt.Sprintf(`resource "datadog_rum_metric" "testing_rum_metric" { + name = %q + event_type = "action" + compute { + aggregation_type = "count" } - group_by { - path = "@browser.name" - tag_name = "browser_name" + } + `, uniq) +} + +func filterDatadogRumMetric(uniq string) string { + return fmt.Sprintf(`resource "datadog_rum_metric" "testing_rum_metric" { + name = %q + event_type = "action" + compute { + aggregation_type = "count" } - uniqueness { - when = "match" + filter { + query = "@service:web-ui" + } + } + `, uniq) +} + +func groupByDatadogRumMetric(uniq string) string { + // Note: the group_bys are not defined in alphabetical order. This is on purpose to verify + // a set behavior rather than a list behavior on the terraform attribute. + return fmt.Sprintf(`resource "datadog_rum_metric" "testing_rum_metric" { + name = %q + event_type = "action" + compute { + aggregation_type = "count" } + group_by { + path = "@service" + tag_name = "service" + } + group_by { + path = "@os" + tag_name = "os" + } } `, uniq) } From 9246a1e46a5602ce6ee3111c5c1eec768eef1246 Mon Sep 17 00:00:00 2001 From: Arthur Hemery Date: Fri, 8 Nov 2024 14:28:18 +0100 Subject: [PATCH 05/10] Base working version --- .../fwprovider/resource_datadog_rum_metric.go | 30 +++++++++---------- docs/resources/rum_metric.md | 2 +- 2 files changed, 16 insertions(+), 16 deletions(-) diff --git a/datadog/fwprovider/resource_datadog_rum_metric.go b/datadog/fwprovider/resource_datadog_rum_metric.go index 0fe327924..78d8cc1d9 100644 --- a/datadog/fwprovider/resource_datadog_rum_metric.go +++ b/datadog/fwprovider/resource_datadog_rum_metric.go @@ -263,21 +263,6 @@ func (r *rumMetricResource) updateState(ctx context.Context, state *rumMetricMod state.EventType = types.StringValue(string(attributes.GetEventType())) - if groupBy, ok := attributes.GetGroupByOk(); ok && len(*groupBy) > 0 { - state.GroupBy = []*rumMetricGroupByModel{} - for _, groupByDdItem := range *groupBy { - groupByTfItem := rumMetricGroupByModel{} - if path, ok := groupByDdItem.GetPathOk(); ok { - groupByTfItem.Path = types.StringValue(*path) - } - if tagName, ok := groupByDdItem.GetTagNameOk(); ok { - groupByTfItem.TagName = types.StringValue(*tagName) - } - - state.GroupBy = append(state.GroupBy, &groupByTfItem) - } - } - if compute, ok := attributes.GetComputeOk(); ok { computeTf := rumMetricComputeModel{} @@ -306,6 +291,21 @@ func (r *rumMetricResource) updateState(ctx context.Context, state *rumMetricMod state.Filter = &filterTf } + if groupBy, ok := attributes.GetGroupByOk(); ok && len(*groupBy) > 0 { + state.GroupBy = []*rumMetricGroupByModel{} + for _, groupByDdItem := range *groupBy { + groupByTfItem := rumMetricGroupByModel{} + if path, ok := groupByDdItem.GetPathOk(); ok { + groupByTfItem.Path = types.StringValue(*path) + } + if tagName, ok := groupByDdItem.GetTagNameOk(); ok { + groupByTfItem.TagName = types.StringValue(*tagName) + } + + state.GroupBy = append(state.GroupBy, &groupByTfItem) + } + } + if uniqueness, ok := attributes.GetUniquenessOk(); ok { uniquenessTf := rumMetricUniquenessModel{} diff --git a/docs/resources/rum_metric.md b/docs/resources/rum_metric.md index 1e9c181bf..c7e00a212 100644 --- a/docs/resources/rum_metric.md +++ b/docs/resources/rum_metric.md @@ -47,7 +47,7 @@ resource "datadog_rum_metric" "foo" { - `compute` (Block, Optional) (see [below for nested schema](#nestedblock--compute)) - `filter` (Block, Optional) (see [below for nested schema](#nestedblock--filter)) -- `group_by` (Block List) (see [below for nested schema](#nestedblock--group_by)) +- `group_by` (Block Set) (see [below for nested schema](#nestedblock--group_by)) - `uniqueness` (Block, Optional) (see [below for nested schema](#nestedblock--uniqueness)) ### Read-Only From a1b48a62dc02720da357b2b879637d17a8654c39 Mon Sep 17 00:00:00 2001 From: Arthur Hemery Date: Fri, 8 Nov 2024 17:35:55 +0100 Subject: [PATCH 06/10] Add cassettes --- .../TestAccRumMetricAttributes.freeze | 1 + .../cassettes/TestAccRumMetricAttributes.yaml | 403 ++++++++++++++++++ .../cassettes/TestAccRumMetricImport.freeze | 1 + .../cassettes/TestAccRumMetricImport.yaml | 136 ++++++ 4 files changed, 541 insertions(+) create mode 100644 datadog/tests/cassettes/TestAccRumMetricAttributes.freeze create mode 100644 datadog/tests/cassettes/TestAccRumMetricAttributes.yaml create mode 100644 datadog/tests/cassettes/TestAccRumMetricImport.freeze create mode 100644 datadog/tests/cassettes/TestAccRumMetricImport.yaml diff --git a/datadog/tests/cassettes/TestAccRumMetricAttributes.freeze b/datadog/tests/cassettes/TestAccRumMetricAttributes.freeze new file mode 100644 index 000000000..f385bcbf6 --- /dev/null +++ b/datadog/tests/cassettes/TestAccRumMetricAttributes.freeze @@ -0,0 +1 @@ +2024-11-08T17:34:41.835001+01:00 \ No newline at end of file diff --git a/datadog/tests/cassettes/TestAccRumMetricAttributes.yaml b/datadog/tests/cassettes/TestAccRumMetricAttributes.yaml new file mode 100644 index 000000000..2d584111d --- /dev/null +++ b/datadog/tests/cassettes/TestAccRumMetricAttributes.yaml @@ -0,0 +1,403 @@ +--- +version: 2 +interactions: + - id: 0 + request: + proto: HTTP/1.1 + proto_major: 1 + proto_minor: 1 + content_length: 166 + transfer_encoding: [] + trailer: {} + host: api.datad0g.com + remote_addr: "" + request_uri: "" + body: | + {"data":{"attributes":{"compute":{"aggregation_type":"count"},"event_type":"action"},"id":"\"tf_TestAccRumMetricAttributes_local_1731083681\"","type":"rum_metrics"}} + form: {} + headers: + Accept: + - application/json + Content-Type: + - application/json + url: https://api.datad0g.com/api/v2/rum/config/metrics + method: POST + response: + proto: HTTP/2.0 + proto_major: 2 + proto_minor: 0 + transfer_encoding: [] + trailer: {} + content_length: 212 + uncompressed: false + body: '{"data":{"id":"tf_TestAccRumMetricAttributes_local_1731083681","type":"rum_metrics","attributes":{"compute":{"aggregation_type":"count","include_percentiles":null,"path":""},"event_type":"action","group_by":[]}}}' + headers: + Content-Type: + - application/vnd.api+json + status: 201 Created + code: 201 + duration: 760.036ms + - id: 1 + request: + proto: HTTP/1.1 + proto_major: 1 + proto_minor: 1 + content_length: 0 + transfer_encoding: [] + trailer: {} + host: api.datad0g.com + remote_addr: "" + request_uri: "" + body: "" + form: {} + headers: + Accept: + - application/json + url: https://api.datad0g.com/api/v2/rum/config/metrics/tf_TestAccRumMetricAttributes_local_1731083681 + method: GET + response: + proto: HTTP/2.0 + proto_major: 2 + proto_minor: 0 + transfer_encoding: [] + trailer: {} + content_length: 212 + uncompressed: false + body: '{"data":{"id":"tf_TestAccRumMetricAttributes_local_1731083681","type":"rum_metrics","attributes":{"compute":{"aggregation_type":"count","include_percentiles":null,"path":""},"event_type":"action","group_by":[]}}}' + headers: + Content-Type: + - application/vnd.api+json + status: 200 OK + code: 200 + duration: 109.609959ms + - id: 2 + request: + proto: HTTP/1.1 + proto_major: 1 + proto_minor: 1 + content_length: 0 + transfer_encoding: [] + trailer: {} + host: api.datad0g.com + remote_addr: "" + request_uri: "" + body: "" + form: {} + headers: + Accept: + - '*/*' + url: https://api.datad0g.com/api/v2/rum/config/metrics/tf_TestAccRumMetricAttributes_local_1731083681 + method: DELETE + response: + proto: HTTP/2.0 + proto_major: 2 + proto_minor: 0 + transfer_encoding: [] + trailer: {} + content_length: 0 + uncompressed: false + body: "" + headers: {} + status: 204 No Content + code: 204 + duration: 108.3615ms + - id: 3 + request: + proto: HTTP/1.1 + proto_major: 1 + proto_minor: 1 + content_length: 219 + transfer_encoding: [] + trailer: {} + host: api.datad0g.com + remote_addr: "" + request_uri: "" + body: | + {"data":{"attributes":{"compute":{"aggregation_type":"distribution","include_percentiles":true,"path":"@duration"},"event_type":"action"},"id":"\"tf_TestAccRumMetricAttributes_local_1731083681\"","type":"rum_metrics"}} + form: {} + headers: + Accept: + - application/json + Content-Type: + - application/json + url: https://api.datad0g.com/api/v2/rum/config/metrics + method: POST + response: + proto: HTTP/2.0 + proto_major: 2 + proto_minor: 0 + transfer_encoding: [] + trailer: {} + content_length: 228 + uncompressed: false + body: '{"data":{"id":"tf_TestAccRumMetricAttributes_local_1731083681","type":"rum_metrics","attributes":{"compute":{"aggregation_type":"distribution","include_percentiles":true,"path":"@duration"},"event_type":"action","group_by":[]}}}' + headers: + Content-Type: + - application/vnd.api+json + status: 201 Created + code: 201 + duration: 1.01709575s + - id: 4 + request: + proto: HTTP/1.1 + proto_major: 1 + proto_minor: 1 + content_length: 0 + transfer_encoding: [] + trailer: {} + host: api.datad0g.com + remote_addr: "" + request_uri: "" + body: "" + form: {} + headers: + Accept: + - application/json + url: https://api.datad0g.com/api/v2/rum/config/metrics/tf_TestAccRumMetricAttributes_local_1731083681 + method: GET + response: + proto: HTTP/2.0 + proto_major: 2 + proto_minor: 0 + transfer_encoding: [] + trailer: {} + content_length: 228 + uncompressed: false + body: '{"data":{"id":"tf_TestAccRumMetricAttributes_local_1731083681","type":"rum_metrics","attributes":{"compute":{"aggregation_type":"distribution","include_percentiles":true,"path":"@duration"},"event_type":"action","group_by":[]}}}' + headers: + Content-Type: + - application/vnd.api+json + status: 200 OK + code: 200 + duration: 104.9915ms + - id: 5 + request: + proto: HTTP/1.1 + proto_major: 1 + proto_minor: 1 + content_length: 0 + transfer_encoding: [] + trailer: {} + host: api.datad0g.com + remote_addr: "" + request_uri: "" + body: "" + form: {} + headers: + Accept: + - '*/*' + url: https://api.datad0g.com/api/v2/rum/config/metrics/tf_TestAccRumMetricAttributes_local_1731083681 + method: DELETE + response: + proto: HTTP/2.0 + proto_major: 2 + proto_minor: 0 + transfer_encoding: [] + trailer: {} + content_length: 0 + uncompressed: false + body: "" + headers: {} + status: 204 No Content + code: 204 + duration: 112.969666ms + - id: 6 + request: + proto: HTTP/1.1 + proto_major: 1 + proto_minor: 1 + content_length: 203 + transfer_encoding: [] + trailer: {} + host: api.datad0g.com + remote_addr: "" + request_uri: "" + body: | + {"data":{"attributes":{"compute":{"aggregation_type":"count"},"event_type":"action","filter":{"query":"@service:web-ui"}},"id":"\"tf_TestAccRumMetricAttributes_local_1731083681\"","type":"rum_metrics"}} + form: {} + headers: + Accept: + - application/json + Content-Type: + - application/json + url: https://api.datad0g.com/api/v2/rum/config/metrics + method: POST + response: + proto: HTTP/2.0 + proto_major: 2 + proto_minor: 0 + transfer_encoding: [] + trailer: {} + content_length: 249 + uncompressed: false + body: '{"data":{"id":"tf_TestAccRumMetricAttributes_local_1731083681","type":"rum_metrics","attributes":{"compute":{"aggregation_type":"count","include_percentiles":null,"path":""},"event_type":"action","filter":{"query":"@service:web-ui"},"group_by":[]}}}' + headers: + Content-Type: + - application/vnd.api+json + status: 201 Created + code: 201 + duration: 853.209917ms + - id: 7 + request: + proto: HTTP/1.1 + proto_major: 1 + proto_minor: 1 + content_length: 0 + transfer_encoding: [] + trailer: {} + host: api.datad0g.com + remote_addr: "" + request_uri: "" + body: "" + form: {} + headers: + Accept: + - application/json + url: https://api.datad0g.com/api/v2/rum/config/metrics/tf_TestAccRumMetricAttributes_local_1731083681 + method: GET + response: + proto: HTTP/2.0 + proto_major: 2 + proto_minor: 0 + transfer_encoding: [] + trailer: {} + content_length: 249 + uncompressed: false + body: '{"data":{"id":"tf_TestAccRumMetricAttributes_local_1731083681","type":"rum_metrics","attributes":{"compute":{"aggregation_type":"count","include_percentiles":null,"path":""},"event_type":"action","filter":{"query":"@service:web-ui"},"group_by":[]}}}' + headers: + Content-Type: + - application/vnd.api+json + status: 200 OK + code: 200 + duration: 103.880667ms + - id: 8 + request: + proto: HTTP/1.1 + proto_major: 1 + proto_minor: 1 + content_length: 0 + transfer_encoding: [] + trailer: {} + host: api.datad0g.com + remote_addr: "" + request_uri: "" + body: "" + form: {} + headers: + Accept: + - '*/*' + url: https://api.datad0g.com/api/v2/rum/config/metrics/tf_TestAccRumMetricAttributes_local_1731083681 + method: DELETE + response: + proto: HTTP/2.0 + proto_major: 2 + proto_minor: 0 + transfer_encoding: [] + trailer: {} + content_length: 0 + uncompressed: false + body: "" + headers: {} + status: 204 No Content + code: 204 + duration: 104.034208ms + - id: 9 + request: + proto: HTTP/1.1 + proto_major: 1 + proto_minor: 1 + content_length: 251 + transfer_encoding: [] + trailer: {} + host: api.datad0g.com + remote_addr: "" + request_uri: "" + body: | + {"data":{"attributes":{"compute":{"aggregation_type":"count"},"event_type":"action","group_by":[{"path":"@os","tag_name":"os"},{"path":"@service","tag_name":"service"}]},"id":"\"tf_TestAccRumMetricAttributes_local_1731083681\"","type":"rum_metrics"}} + form: {} + headers: + Accept: + - application/json + Content-Type: + - application/json + url: https://api.datad0g.com/api/v2/rum/config/metrics + method: POST + response: + proto: HTTP/2.0 + proto_major: 2 + proto_minor: 0 + transfer_encoding: [] + trailer: {} + content_length: 283 + uncompressed: false + body: '{"data":{"id":"tf_TestAccRumMetricAttributes_local_1731083681","type":"rum_metrics","attributes":{"compute":{"aggregation_type":"count","include_percentiles":null,"path":""},"event_type":"action","group_by":[{"path":"@os","tag_name":"os"},{"path":"@service","tag_name":"service"}]}}}' + headers: + Content-Type: + - application/vnd.api+json + status: 201 Created + code: 201 + duration: 965.583375ms + - id: 10 + request: + proto: HTTP/1.1 + proto_major: 1 + proto_minor: 1 + content_length: 0 + transfer_encoding: [] + trailer: {} + host: api.datad0g.com + remote_addr: "" + request_uri: "" + body: "" + form: {} + headers: + Accept: + - application/json + url: https://api.datad0g.com/api/v2/rum/config/metrics/tf_TestAccRumMetricAttributes_local_1731083681 + method: GET + response: + proto: HTTP/2.0 + proto_major: 2 + proto_minor: 0 + transfer_encoding: [] + trailer: {} + content_length: 283 + uncompressed: false + body: '{"data":{"id":"tf_TestAccRumMetricAttributes_local_1731083681","type":"rum_metrics","attributes":{"compute":{"aggregation_type":"count","include_percentiles":null,"path":""},"event_type":"action","group_by":[{"path":"@os","tag_name":"os"},{"path":"@service","tag_name":"service"}]}}}' + headers: + Content-Type: + - application/vnd.api+json + status: 200 OK + code: 200 + duration: 103.185083ms + - id: 11 + request: + proto: HTTP/1.1 + proto_major: 1 + proto_minor: 1 + content_length: 0 + transfer_encoding: [] + trailer: {} + host: api.datad0g.com + remote_addr: "" + request_uri: "" + body: "" + form: {} + headers: + Accept: + - '*/*' + url: https://api.datad0g.com/api/v2/rum/config/metrics/tf_TestAccRumMetricAttributes_local_1731083681 + method: DELETE + response: + proto: HTTP/2.0 + proto_major: 2 + proto_minor: 0 + transfer_encoding: [] + trailer: {} + content_length: 0 + uncompressed: false + body: "" + headers: {} + status: 204 No Content + code: 204 + duration: 109.502792ms diff --git a/datadog/tests/cassettes/TestAccRumMetricImport.freeze b/datadog/tests/cassettes/TestAccRumMetricImport.freeze new file mode 100644 index 000000000..86645c8c6 --- /dev/null +++ b/datadog/tests/cassettes/TestAccRumMetricImport.freeze @@ -0,0 +1 @@ +2024-11-08T17:34:41.835006+01:00 \ No newline at end of file diff --git a/datadog/tests/cassettes/TestAccRumMetricImport.yaml b/datadog/tests/cassettes/TestAccRumMetricImport.yaml new file mode 100644 index 000000000..0990b7fef --- /dev/null +++ b/datadog/tests/cassettes/TestAccRumMetricImport.yaml @@ -0,0 +1,136 @@ +--- +version: 2 +interactions: + - id: 0 + request: + proto: HTTP/1.1 + proto_major: 1 + proto_minor: 1 + content_length: 162 + transfer_encoding: [] + trailer: {} + host: api.datad0g.com + remote_addr: "" + request_uri: "" + body: | + {"data":{"attributes":{"compute":{"aggregation_type":"count"},"event_type":"action"},"id":"\"tf_TestAccRumMetricImport_local_1731083681\"","type":"rum_metrics"}} + form: {} + headers: + Accept: + - application/json + Content-Type: + - application/json + url: https://api.datad0g.com/api/v2/rum/config/metrics + method: POST + response: + proto: HTTP/2.0 + proto_major: 2 + proto_minor: 0 + transfer_encoding: [] + trailer: {} + content_length: 208 + uncompressed: false + body: '{"data":{"id":"tf_TestAccRumMetricImport_local_1731083681","type":"rum_metrics","attributes":{"compute":{"aggregation_type":"count","include_percentiles":null,"path":""},"event_type":"action","group_by":[]}}}' + headers: + Content-Type: + - application/vnd.api+json + status: 201 Created + code: 201 + duration: 714.608459ms + - id: 1 + request: + proto: HTTP/1.1 + proto_major: 1 + proto_minor: 1 + content_length: 0 + transfer_encoding: [] + trailer: {} + host: api.datad0g.com + remote_addr: "" + request_uri: "" + body: "" + form: {} + headers: + Accept: + - application/json + url: https://api.datad0g.com/api/v2/rum/config/metrics/tf_TestAccRumMetricImport_local_1731083681 + method: GET + response: + proto: HTTP/2.0 + proto_major: 2 + proto_minor: 0 + transfer_encoding: [] + trailer: {} + content_length: 208 + uncompressed: false + body: '{"data":{"id":"tf_TestAccRumMetricImport_local_1731083681","type":"rum_metrics","attributes":{"compute":{"aggregation_type":"count","include_percentiles":null,"path":""},"event_type":"action","group_by":[]}}}' + headers: + Content-Type: + - application/vnd.api+json + status: 200 OK + code: 200 + duration: 105.67175ms + - id: 2 + request: + proto: HTTP/1.1 + proto_major: 1 + proto_minor: 1 + content_length: 0 + transfer_encoding: [] + trailer: {} + host: api.datad0g.com + remote_addr: "" + request_uri: "" + body: "" + form: {} + headers: + Accept: + - application/json + url: https://api.datad0g.com/api/v2/rum/config/metrics/tf_TestAccRumMetricImport_local_1731083681 + method: GET + response: + proto: HTTP/2.0 + proto_major: 2 + proto_minor: 0 + transfer_encoding: [] + trailer: {} + content_length: 208 + uncompressed: false + body: '{"data":{"id":"tf_TestAccRumMetricImport_local_1731083681","type":"rum_metrics","attributes":{"compute":{"aggregation_type":"count","include_percentiles":null,"path":""},"event_type":"action","group_by":[]}}}' + headers: + Content-Type: + - application/vnd.api+json + status: 200 OK + code: 200 + duration: 109.853708ms + - id: 3 + request: + proto: HTTP/1.1 + proto_major: 1 + proto_minor: 1 + content_length: 0 + transfer_encoding: [] + trailer: {} + host: api.datad0g.com + remote_addr: "" + request_uri: "" + body: "" + form: {} + headers: + Accept: + - '*/*' + url: https://api.datad0g.com/api/v2/rum/config/metrics/tf_TestAccRumMetricImport_local_1731083681 + method: DELETE + response: + proto: HTTP/2.0 + proto_major: 2 + proto_minor: 0 + transfer_encoding: [] + trailer: {} + content_length: 0 + uncompressed: false + body: "" + headers: {} + status: 204 No Content + code: 204 + duration: 106.122167ms From a1889845865dd16f83dcbd123f90ec2a6ae48295 Mon Sep 17 00:00:00 2001 From: Arthur Hemery Date: Fri, 8 Nov 2024 17:41:22 +0100 Subject: [PATCH 07/10] Doc fixes --- docs/resources/rum_metric.md | 9 +++++---- .../resources/datadog_rum_metric/import.sh | 2 +- .../resources/datadog_rum_metric/resource.tf | 7 ++++--- .../resources/datadog_rum_metrics/import.sh | 1 - .../resources/datadog_rum_metrics/resource.tf | 20 ------------------- 5 files changed, 10 insertions(+), 29 deletions(-) delete mode 100644 examples/resources/datadog_rum_metrics/import.sh delete mode 100644 examples/resources/datadog_rum_metrics/resource.tf diff --git a/docs/resources/rum_metric.md b/docs/resources/rum_metric.md index c7e00a212..63f2b8531 100644 --- a/docs/resources/rum_metric.md +++ b/docs/resources/rum_metric.md @@ -15,15 +15,16 @@ Provides a Datadog RumMetric resource. This can be used to create and manage Dat ```terraform # Create new rum_metric resource -resource "datadog_rum_metric" "foo" { +resource "datadog_rum_metric" "testing_rum_metric" { + name = "testing.rum.metric" compute { aggregation_type = "distribution" - include_percentiles = True + include_percentiles = true path = "@duration" } event_type = "session" filter { - query = "@service:web-ui: " + query = "@service:web-ui" } group_by { path = "@browser.name" @@ -96,5 +97,5 @@ Optional: Import is supported using the following syntax: ```shell -terraform import datadog_rum_metric.new_list "" +terraform import datadog_rum_metric.testing_rum_metric "testing.rum.metric" ``` diff --git a/examples/resources/datadog_rum_metric/import.sh b/examples/resources/datadog_rum_metric/import.sh index 43d00dbfc..9d5d2678c 100644 --- a/examples/resources/datadog_rum_metric/import.sh +++ b/examples/resources/datadog_rum_metric/import.sh @@ -1 +1 @@ -terraform import datadog_rum_metric.new_list "" \ No newline at end of file +terraform import datadog_rum_metric.testing_rum_metric "testing.rum.metric" \ No newline at end of file diff --git a/examples/resources/datadog_rum_metric/resource.tf b/examples/resources/datadog_rum_metric/resource.tf index bd7c48ebd..610dd623b 100644 --- a/examples/resources/datadog_rum_metric/resource.tf +++ b/examples/resources/datadog_rum_metric/resource.tf @@ -1,14 +1,15 @@ # Create new rum_metric resource -resource "datadog_rum_metric" "foo" { +resource "datadog_rum_metric" "testing_rum_metric" { + name = "testing.rum.metric" compute { aggregation_type = "distribution" - include_percentiles = True + include_percentiles = true path = "@duration" } event_type = "session" filter { - query = "@service:web-ui: " + query = "@service:web-ui" } group_by { path = "@browser.name" diff --git a/examples/resources/datadog_rum_metrics/import.sh b/examples/resources/datadog_rum_metrics/import.sh deleted file mode 100644 index d3aadea1b..000000000 --- a/examples/resources/datadog_rum_metrics/import.sh +++ /dev/null @@ -1 +0,0 @@ -terraform import datadog_rum_metrics.new_list "" \ No newline at end of file diff --git a/examples/resources/datadog_rum_metrics/resource.tf b/examples/resources/datadog_rum_metrics/resource.tf deleted file mode 100644 index 2fc54d628..000000000 --- a/examples/resources/datadog_rum_metrics/resource.tf +++ /dev/null @@ -1,20 +0,0 @@ -# Create new rum_metrics resource - -resource "datadog_rum_metrics" "foo" { - compute { - aggregation_type = "distribution" - include_percentiles = True - path = "@duration" - } - event_type = "session" - filter { - query = "@service:web-ui: " - } - group_by { - path = "@browser.name" - tag_name = "browser_name" - } - uniqueness { - when = "match" - } -} \ No newline at end of file From a4391ea663eac6058a01d46d16418cb163947fbf Mon Sep 17 00:00:00 2001 From: Arthur Hemery Date: Wed, 13 Nov 2024 14:55:17 +0100 Subject: [PATCH 08/10] Fix cassettes url --- .../TestAccRumMetricAttributes.freeze | 2 +- .../cassettes/TestAccRumMetricAttributes.yaml | 108 +++++++++--------- .../cassettes/TestAccRumMetricImport.freeze | 2 +- .../cassettes/TestAccRumMetricImport.yaml | 38 +++--- 4 files changed, 75 insertions(+), 75 deletions(-) diff --git a/datadog/tests/cassettes/TestAccRumMetricAttributes.freeze b/datadog/tests/cassettes/TestAccRumMetricAttributes.freeze index f385bcbf6..5ff118de3 100644 --- a/datadog/tests/cassettes/TestAccRumMetricAttributes.freeze +++ b/datadog/tests/cassettes/TestAccRumMetricAttributes.freeze @@ -1 +1 @@ -2024-11-08T17:34:41.835001+01:00 \ No newline at end of file +2024-11-13T14:53:37.123281+01:00 \ No newline at end of file diff --git a/datadog/tests/cassettes/TestAccRumMetricAttributes.yaml b/datadog/tests/cassettes/TestAccRumMetricAttributes.yaml index 2d584111d..3ce7c4b6d 100644 --- a/datadog/tests/cassettes/TestAccRumMetricAttributes.yaml +++ b/datadog/tests/cassettes/TestAccRumMetricAttributes.yaml @@ -9,18 +9,18 @@ interactions: content_length: 166 transfer_encoding: [] trailer: {} - host: api.datad0g.com + host: api.datadoghq.com remote_addr: "" request_uri: "" body: | - {"data":{"attributes":{"compute":{"aggregation_type":"count"},"event_type":"action"},"id":"\"tf_TestAccRumMetricAttributes_local_1731083681\"","type":"rum_metrics"}} + {"data":{"attributes":{"compute":{"aggregation_type":"count"},"event_type":"action"},"id":"\"tf_TestAccRumMetricAttributes_local_1731506017\"","type":"rum_metrics"}} form: {} headers: Accept: - application/json Content-Type: - application/json - url: https://api.datad0g.com/api/v2/rum/config/metrics + url: https://api.datadoghq.com/api/v2/rum/config/metrics method: POST response: proto: HTTP/2.0 @@ -28,15 +28,15 @@ interactions: proto_minor: 0 transfer_encoding: [] trailer: {} - content_length: 212 + content_length: 175 uncompressed: false - body: '{"data":{"id":"tf_TestAccRumMetricAttributes_local_1731083681","type":"rum_metrics","attributes":{"compute":{"aggregation_type":"count","include_percentiles":null,"path":""},"event_type":"action","group_by":[]}}}' + body: '{"data":{"id":"tf_TestAccRumMetricAttributes_local_1731506017","type":"rum_metrics","attributes":{"compute":{"aggregation_type":"count"},"event_type":"action","group_by":[]}}}' headers: Content-Type: - application/vnd.api+json status: 201 Created code: 201 - duration: 760.036ms + duration: 815.741958ms - id: 1 request: proto: HTTP/1.1 @@ -45,7 +45,7 @@ interactions: content_length: 0 transfer_encoding: [] trailer: {} - host: api.datad0g.com + host: api.datadoghq.com remote_addr: "" request_uri: "" body: "" @@ -53,7 +53,7 @@ interactions: headers: Accept: - application/json - url: https://api.datad0g.com/api/v2/rum/config/metrics/tf_TestAccRumMetricAttributes_local_1731083681 + url: https://api.datadoghq.com/api/v2/rum/config/metrics/tf_TestAccRumMetricAttributes_local_1731506017 method: GET response: proto: HTTP/2.0 @@ -61,15 +61,15 @@ interactions: proto_minor: 0 transfer_encoding: [] trailer: {} - content_length: 212 + content_length: 175 uncompressed: false - body: '{"data":{"id":"tf_TestAccRumMetricAttributes_local_1731083681","type":"rum_metrics","attributes":{"compute":{"aggregation_type":"count","include_percentiles":null,"path":""},"event_type":"action","group_by":[]}}}' + body: '{"data":{"id":"tf_TestAccRumMetricAttributes_local_1731506017","type":"rum_metrics","attributes":{"compute":{"aggregation_type":"count"},"event_type":"action","group_by":[]}}}' headers: Content-Type: - application/vnd.api+json status: 200 OK code: 200 - duration: 109.609959ms + duration: 109.067958ms - id: 2 request: proto: HTTP/1.1 @@ -78,7 +78,7 @@ interactions: content_length: 0 transfer_encoding: [] trailer: {} - host: api.datad0g.com + host: api.datadoghq.com remote_addr: "" request_uri: "" body: "" @@ -86,7 +86,7 @@ interactions: headers: Accept: - '*/*' - url: https://api.datad0g.com/api/v2/rum/config/metrics/tf_TestAccRumMetricAttributes_local_1731083681 + url: https://api.datadoghq.com/api/v2/rum/config/metrics/tf_TestAccRumMetricAttributes_local_1731506017 method: DELETE response: proto: HTTP/2.0 @@ -100,7 +100,7 @@ interactions: headers: {} status: 204 No Content code: 204 - duration: 108.3615ms + duration: 117.488125ms - id: 3 request: proto: HTTP/1.1 @@ -109,18 +109,18 @@ interactions: content_length: 219 transfer_encoding: [] trailer: {} - host: api.datad0g.com + host: api.datadoghq.com remote_addr: "" request_uri: "" body: | - {"data":{"attributes":{"compute":{"aggregation_type":"distribution","include_percentiles":true,"path":"@duration"},"event_type":"action"},"id":"\"tf_TestAccRumMetricAttributes_local_1731083681\"","type":"rum_metrics"}} + {"data":{"attributes":{"compute":{"aggregation_type":"distribution","include_percentiles":true,"path":"@duration"},"event_type":"action"},"id":"\"tf_TestAccRumMetricAttributes_local_1731506017\"","type":"rum_metrics"}} form: {} headers: Accept: - application/json Content-Type: - application/json - url: https://api.datad0g.com/api/v2/rum/config/metrics + url: https://api.datadoghq.com/api/v2/rum/config/metrics method: POST response: proto: HTTP/2.0 @@ -130,13 +130,13 @@ interactions: trailer: {} content_length: 228 uncompressed: false - body: '{"data":{"id":"tf_TestAccRumMetricAttributes_local_1731083681","type":"rum_metrics","attributes":{"compute":{"aggregation_type":"distribution","include_percentiles":true,"path":"@duration"},"event_type":"action","group_by":[]}}}' + body: '{"data":{"id":"tf_TestAccRumMetricAttributes_local_1731506017","type":"rum_metrics","attributes":{"compute":{"aggregation_type":"distribution","include_percentiles":true,"path":"@duration"},"event_type":"action","group_by":[]}}}' headers: Content-Type: - application/vnd.api+json status: 201 Created code: 201 - duration: 1.01709575s + duration: 1.02972725s - id: 4 request: proto: HTTP/1.1 @@ -145,7 +145,7 @@ interactions: content_length: 0 transfer_encoding: [] trailer: {} - host: api.datad0g.com + host: api.datadoghq.com remote_addr: "" request_uri: "" body: "" @@ -153,7 +153,7 @@ interactions: headers: Accept: - application/json - url: https://api.datad0g.com/api/v2/rum/config/metrics/tf_TestAccRumMetricAttributes_local_1731083681 + url: https://api.datadoghq.com/api/v2/rum/config/metrics/tf_TestAccRumMetricAttributes_local_1731506017 method: GET response: proto: HTTP/2.0 @@ -163,13 +163,13 @@ interactions: trailer: {} content_length: 228 uncompressed: false - body: '{"data":{"id":"tf_TestAccRumMetricAttributes_local_1731083681","type":"rum_metrics","attributes":{"compute":{"aggregation_type":"distribution","include_percentiles":true,"path":"@duration"},"event_type":"action","group_by":[]}}}' + body: '{"data":{"id":"tf_TestAccRumMetricAttributes_local_1731506017","type":"rum_metrics","attributes":{"compute":{"aggregation_type":"distribution","include_percentiles":true,"path":"@duration"},"event_type":"action","group_by":[]}}}' headers: Content-Type: - application/vnd.api+json status: 200 OK code: 200 - duration: 104.9915ms + duration: 108.842709ms - id: 5 request: proto: HTTP/1.1 @@ -178,7 +178,7 @@ interactions: content_length: 0 transfer_encoding: [] trailer: {} - host: api.datad0g.com + host: api.datadoghq.com remote_addr: "" request_uri: "" body: "" @@ -186,7 +186,7 @@ interactions: headers: Accept: - '*/*' - url: https://api.datad0g.com/api/v2/rum/config/metrics/tf_TestAccRumMetricAttributes_local_1731083681 + url: https://api.datadoghq.com/api/v2/rum/config/metrics/tf_TestAccRumMetricAttributes_local_1731506017 method: DELETE response: proto: HTTP/2.0 @@ -200,7 +200,7 @@ interactions: headers: {} status: 204 No Content code: 204 - duration: 112.969666ms + duration: 112.006667ms - id: 6 request: proto: HTTP/1.1 @@ -209,18 +209,18 @@ interactions: content_length: 203 transfer_encoding: [] trailer: {} - host: api.datad0g.com + host: api.datadoghq.com remote_addr: "" request_uri: "" body: | - {"data":{"attributes":{"compute":{"aggregation_type":"count"},"event_type":"action","filter":{"query":"@service:web-ui"}},"id":"\"tf_TestAccRumMetricAttributes_local_1731083681\"","type":"rum_metrics"}} + {"data":{"attributes":{"compute":{"aggregation_type":"count"},"event_type":"action","filter":{"query":"@service:web-ui"}},"id":"\"tf_TestAccRumMetricAttributes_local_1731506017\"","type":"rum_metrics"}} form: {} headers: Accept: - application/json Content-Type: - application/json - url: https://api.datad0g.com/api/v2/rum/config/metrics + url: https://api.datadoghq.com/api/v2/rum/config/metrics method: POST response: proto: HTTP/2.0 @@ -228,15 +228,15 @@ interactions: proto_minor: 0 transfer_encoding: [] trailer: {} - content_length: 249 + content_length: 212 uncompressed: false - body: '{"data":{"id":"tf_TestAccRumMetricAttributes_local_1731083681","type":"rum_metrics","attributes":{"compute":{"aggregation_type":"count","include_percentiles":null,"path":""},"event_type":"action","filter":{"query":"@service:web-ui"},"group_by":[]}}}' + body: '{"data":{"id":"tf_TestAccRumMetricAttributes_local_1731506017","type":"rum_metrics","attributes":{"compute":{"aggregation_type":"count"},"event_type":"action","filter":{"query":"@service:web-ui"},"group_by":[]}}}' headers: Content-Type: - application/vnd.api+json status: 201 Created code: 201 - duration: 853.209917ms + duration: 247.393ms - id: 7 request: proto: HTTP/1.1 @@ -245,7 +245,7 @@ interactions: content_length: 0 transfer_encoding: [] trailer: {} - host: api.datad0g.com + host: api.datadoghq.com remote_addr: "" request_uri: "" body: "" @@ -253,7 +253,7 @@ interactions: headers: Accept: - application/json - url: https://api.datad0g.com/api/v2/rum/config/metrics/tf_TestAccRumMetricAttributes_local_1731083681 + url: https://api.datadoghq.com/api/v2/rum/config/metrics/tf_TestAccRumMetricAttributes_local_1731506017 method: GET response: proto: HTTP/2.0 @@ -261,15 +261,15 @@ interactions: proto_minor: 0 transfer_encoding: [] trailer: {} - content_length: 249 + content_length: 212 uncompressed: false - body: '{"data":{"id":"tf_TestAccRumMetricAttributes_local_1731083681","type":"rum_metrics","attributes":{"compute":{"aggregation_type":"count","include_percentiles":null,"path":""},"event_type":"action","filter":{"query":"@service:web-ui"},"group_by":[]}}}' + body: '{"data":{"id":"tf_TestAccRumMetricAttributes_local_1731506017","type":"rum_metrics","attributes":{"compute":{"aggregation_type":"count"},"event_type":"action","filter":{"query":"@service:web-ui"},"group_by":[]}}}' headers: Content-Type: - application/vnd.api+json status: 200 OK code: 200 - duration: 103.880667ms + duration: 107.427541ms - id: 8 request: proto: HTTP/1.1 @@ -278,7 +278,7 @@ interactions: content_length: 0 transfer_encoding: [] trailer: {} - host: api.datad0g.com + host: api.datadoghq.com remote_addr: "" request_uri: "" body: "" @@ -286,7 +286,7 @@ interactions: headers: Accept: - '*/*' - url: https://api.datad0g.com/api/v2/rum/config/metrics/tf_TestAccRumMetricAttributes_local_1731083681 + url: https://api.datadoghq.com/api/v2/rum/config/metrics/tf_TestAccRumMetricAttributes_local_1731506017 method: DELETE response: proto: HTTP/2.0 @@ -300,7 +300,7 @@ interactions: headers: {} status: 204 No Content code: 204 - duration: 104.034208ms + duration: 107.245458ms - id: 9 request: proto: HTTP/1.1 @@ -309,18 +309,18 @@ interactions: content_length: 251 transfer_encoding: [] trailer: {} - host: api.datad0g.com + host: api.datadoghq.com remote_addr: "" request_uri: "" body: | - {"data":{"attributes":{"compute":{"aggregation_type":"count"},"event_type":"action","group_by":[{"path":"@os","tag_name":"os"},{"path":"@service","tag_name":"service"}]},"id":"\"tf_TestAccRumMetricAttributes_local_1731083681\"","type":"rum_metrics"}} + {"data":{"attributes":{"compute":{"aggregation_type":"count"},"event_type":"action","group_by":[{"path":"@os","tag_name":"os"},{"path":"@service","tag_name":"service"}]},"id":"\"tf_TestAccRumMetricAttributes_local_1731506017\"","type":"rum_metrics"}} form: {} headers: Accept: - application/json Content-Type: - application/json - url: https://api.datad0g.com/api/v2/rum/config/metrics + url: https://api.datadoghq.com/api/v2/rum/config/metrics method: POST response: proto: HTTP/2.0 @@ -328,15 +328,15 @@ interactions: proto_minor: 0 transfer_encoding: [] trailer: {} - content_length: 283 + content_length: 246 uncompressed: false - body: '{"data":{"id":"tf_TestAccRumMetricAttributes_local_1731083681","type":"rum_metrics","attributes":{"compute":{"aggregation_type":"count","include_percentiles":null,"path":""},"event_type":"action","group_by":[{"path":"@os","tag_name":"os"},{"path":"@service","tag_name":"service"}]}}}' + body: '{"data":{"id":"tf_TestAccRumMetricAttributes_local_1731506017","type":"rum_metrics","attributes":{"compute":{"aggregation_type":"count"},"event_type":"action","group_by":[{"path":"@os","tag_name":"os"},{"path":"@service","tag_name":"service"}]}}}' headers: Content-Type: - application/vnd.api+json status: 201 Created code: 201 - duration: 965.583375ms + duration: 550.922458ms - id: 10 request: proto: HTTP/1.1 @@ -345,7 +345,7 @@ interactions: content_length: 0 transfer_encoding: [] trailer: {} - host: api.datad0g.com + host: api.datadoghq.com remote_addr: "" request_uri: "" body: "" @@ -353,7 +353,7 @@ interactions: headers: Accept: - application/json - url: https://api.datad0g.com/api/v2/rum/config/metrics/tf_TestAccRumMetricAttributes_local_1731083681 + url: https://api.datadoghq.com/api/v2/rum/config/metrics/tf_TestAccRumMetricAttributes_local_1731506017 method: GET response: proto: HTTP/2.0 @@ -361,15 +361,15 @@ interactions: proto_minor: 0 transfer_encoding: [] trailer: {} - content_length: 283 + content_length: 246 uncompressed: false - body: '{"data":{"id":"tf_TestAccRumMetricAttributes_local_1731083681","type":"rum_metrics","attributes":{"compute":{"aggregation_type":"count","include_percentiles":null,"path":""},"event_type":"action","group_by":[{"path":"@os","tag_name":"os"},{"path":"@service","tag_name":"service"}]}}}' + body: '{"data":{"id":"tf_TestAccRumMetricAttributes_local_1731506017","type":"rum_metrics","attributes":{"compute":{"aggregation_type":"count"},"event_type":"action","group_by":[{"path":"@os","tag_name":"os"},{"path":"@service","tag_name":"service"}]}}}' headers: Content-Type: - application/vnd.api+json status: 200 OK code: 200 - duration: 103.185083ms + duration: 107.373583ms - id: 11 request: proto: HTTP/1.1 @@ -378,7 +378,7 @@ interactions: content_length: 0 transfer_encoding: [] trailer: {} - host: api.datad0g.com + host: api.datadoghq.com remote_addr: "" request_uri: "" body: "" @@ -386,7 +386,7 @@ interactions: headers: Accept: - '*/*' - url: https://api.datad0g.com/api/v2/rum/config/metrics/tf_TestAccRumMetricAttributes_local_1731083681 + url: https://api.datadoghq.com/api/v2/rum/config/metrics/tf_TestAccRumMetricAttributes_local_1731506017 method: DELETE response: proto: HTTP/2.0 @@ -400,4 +400,4 @@ interactions: headers: {} status: 204 No Content code: 204 - duration: 109.502792ms + duration: 108.528417ms diff --git a/datadog/tests/cassettes/TestAccRumMetricImport.freeze b/datadog/tests/cassettes/TestAccRumMetricImport.freeze index 86645c8c6..05e44395d 100644 --- a/datadog/tests/cassettes/TestAccRumMetricImport.freeze +++ b/datadog/tests/cassettes/TestAccRumMetricImport.freeze @@ -1 +1 @@ -2024-11-08T17:34:41.835006+01:00 \ No newline at end of file +2024-11-13T14:53:37.123287+01:00 \ No newline at end of file diff --git a/datadog/tests/cassettes/TestAccRumMetricImport.yaml b/datadog/tests/cassettes/TestAccRumMetricImport.yaml index 0990b7fef..6a2f59a8b 100644 --- a/datadog/tests/cassettes/TestAccRumMetricImport.yaml +++ b/datadog/tests/cassettes/TestAccRumMetricImport.yaml @@ -9,18 +9,18 @@ interactions: content_length: 162 transfer_encoding: [] trailer: {} - host: api.datad0g.com + host: api.datadoghq.com remote_addr: "" request_uri: "" body: | - {"data":{"attributes":{"compute":{"aggregation_type":"count"},"event_type":"action"},"id":"\"tf_TestAccRumMetricImport_local_1731083681\"","type":"rum_metrics"}} + {"data":{"attributes":{"compute":{"aggregation_type":"count"},"event_type":"action"},"id":"\"tf_TestAccRumMetricImport_local_1731506017\"","type":"rum_metrics"}} form: {} headers: Accept: - application/json Content-Type: - application/json - url: https://api.datad0g.com/api/v2/rum/config/metrics + url: https://api.datadoghq.com/api/v2/rum/config/metrics method: POST response: proto: HTTP/2.0 @@ -28,15 +28,15 @@ interactions: proto_minor: 0 transfer_encoding: [] trailer: {} - content_length: 208 + content_length: 171 uncompressed: false - body: '{"data":{"id":"tf_TestAccRumMetricImport_local_1731083681","type":"rum_metrics","attributes":{"compute":{"aggregation_type":"count","include_percentiles":null,"path":""},"event_type":"action","group_by":[]}}}' + body: '{"data":{"id":"tf_TestAccRumMetricImport_local_1731506017","type":"rum_metrics","attributes":{"compute":{"aggregation_type":"count"},"event_type":"action","group_by":[]}}}' headers: Content-Type: - application/vnd.api+json status: 201 Created code: 201 - duration: 714.608459ms + duration: 707.791ms - id: 1 request: proto: HTTP/1.1 @@ -45,7 +45,7 @@ interactions: content_length: 0 transfer_encoding: [] trailer: {} - host: api.datad0g.com + host: api.datadoghq.com remote_addr: "" request_uri: "" body: "" @@ -53,7 +53,7 @@ interactions: headers: Accept: - application/json - url: https://api.datad0g.com/api/v2/rum/config/metrics/tf_TestAccRumMetricImport_local_1731083681 + url: https://api.datadoghq.com/api/v2/rum/config/metrics/tf_TestAccRumMetricImport_local_1731506017 method: GET response: proto: HTTP/2.0 @@ -61,15 +61,15 @@ interactions: proto_minor: 0 transfer_encoding: [] trailer: {} - content_length: 208 + content_length: 171 uncompressed: false - body: '{"data":{"id":"tf_TestAccRumMetricImport_local_1731083681","type":"rum_metrics","attributes":{"compute":{"aggregation_type":"count","include_percentiles":null,"path":""},"event_type":"action","group_by":[]}}}' + body: '{"data":{"id":"tf_TestAccRumMetricImport_local_1731506017","type":"rum_metrics","attributes":{"compute":{"aggregation_type":"count"},"event_type":"action","group_by":[]}}}' headers: Content-Type: - application/vnd.api+json status: 200 OK code: 200 - duration: 105.67175ms + duration: 108.442334ms - id: 2 request: proto: HTTP/1.1 @@ -78,7 +78,7 @@ interactions: content_length: 0 transfer_encoding: [] trailer: {} - host: api.datad0g.com + host: api.datadoghq.com remote_addr: "" request_uri: "" body: "" @@ -86,7 +86,7 @@ interactions: headers: Accept: - application/json - url: https://api.datad0g.com/api/v2/rum/config/metrics/tf_TestAccRumMetricImport_local_1731083681 + url: https://api.datadoghq.com/api/v2/rum/config/metrics/tf_TestAccRumMetricImport_local_1731506017 method: GET response: proto: HTTP/2.0 @@ -94,15 +94,15 @@ interactions: proto_minor: 0 transfer_encoding: [] trailer: {} - content_length: 208 + content_length: 171 uncompressed: false - body: '{"data":{"id":"tf_TestAccRumMetricImport_local_1731083681","type":"rum_metrics","attributes":{"compute":{"aggregation_type":"count","include_percentiles":null,"path":""},"event_type":"action","group_by":[]}}}' + body: '{"data":{"id":"tf_TestAccRumMetricImport_local_1731506017","type":"rum_metrics","attributes":{"compute":{"aggregation_type":"count"},"event_type":"action","group_by":[]}}}' headers: Content-Type: - application/vnd.api+json status: 200 OK code: 200 - duration: 109.853708ms + duration: 109.190917ms - id: 3 request: proto: HTTP/1.1 @@ -111,7 +111,7 @@ interactions: content_length: 0 transfer_encoding: [] trailer: {} - host: api.datad0g.com + host: api.datadoghq.com remote_addr: "" request_uri: "" body: "" @@ -119,7 +119,7 @@ interactions: headers: Accept: - '*/*' - url: https://api.datad0g.com/api/v2/rum/config/metrics/tf_TestAccRumMetricImport_local_1731083681 + url: https://api.datadoghq.com/api/v2/rum/config/metrics/tf_TestAccRumMetricImport_local_1731506017 method: DELETE response: proto: HTTP/2.0 @@ -133,4 +133,4 @@ interactions: headers: {} status: 204 No Content code: 204 - duration: 106.122167ms + duration: 111.724542ms From 01d04c3f10348bbbc9ba13614e8b99bd888df25d Mon Sep 17 00:00:00 2001 From: Arthur Hemery Date: Thu, 14 Nov 2024 08:47:03 +0100 Subject: [PATCH 09/10] More tests --- .../fwprovider/resource_datadog_rum_metric.go | 13 +- .../TestAccRumMetricAttributes.freeze | 2 +- .../cassettes/TestAccRumMetricAttributes.yaml | 390 ++++++++++++++++-- .../cassettes/TestAccRumMetricImport.freeze | 2 +- .../cassettes/TestAccRumMetricImport.yaml | 24 +- .../tests/resource_datadog_rum_metric_test.go | 105 ++++- 6 files changed, 462 insertions(+), 74 deletions(-) diff --git a/datadog/fwprovider/resource_datadog_rum_metric.go b/datadog/fwprovider/resource_datadog_rum_metric.go index 78d8cc1d9..ba3754c6b 100644 --- a/datadog/fwprovider/resource_datadog_rum_metric.go +++ b/datadog/fwprovider/resource_datadog_rum_metric.go @@ -105,6 +105,9 @@ func (r *rumMetricResource) Schema(_ context.Context, _ resource.SchemaRequest, "path": schema.StringAttribute{ Description: "The path to the value the rum-based metric will aggregate on. Only present when `aggregation_type` is `distribution`.", Optional: true, + PlanModifiers: []planmodifier.String{ + stringplanmodifier.RequiresReplace(), + }, }, }, }, @@ -212,7 +215,7 @@ func (r *rumMetricResource) Update(ctx context.Context, request resource.UpdateR return } - id := state.ID.ValueString() + id := state.Name.ValueString() body, diags := r.buildRumMetricUpdateRequestBody(ctx, &state) response.Diagnostics.Append(diags...) @@ -273,9 +276,7 @@ func (r *rumMetricResource) updateState(ctx context.Context, state *rumMetricMod computeTf.IncludePercentiles = types.BoolValue(*includePercentiles) } if path, ok := compute.GetPathOk(); ok { - if *path != "" { - computeTf.Path = types.StringValue(*path) - } + computeTf.Path = types.StringValue(*path) } state.Compute = &computeTf @@ -366,7 +367,7 @@ func (r *rumMetricResource) buildRumMetricRequestBody(ctx context.Context, state req := datadogV2.NewRumMetricCreateRequestWithDefaults() req.Data = *datadogV2.NewRumMetricCreateDataWithDefaults() - req.Data.SetId(state.Name.String()) + req.Data.SetId(state.Name.ValueString()) req.Data.SetAttributes(*attributes) return req, diags @@ -410,7 +411,7 @@ func (r *rumMetricResource) buildRumMetricUpdateRequestBody(ctx context.Context, req := datadogV2.NewRumMetricUpdateRequestWithDefaults() req.Data = *datadogV2.NewRumMetricUpdateDataWithDefaults() - req.Data.SetId(state.Name.String()) + req.Data.SetId(state.Name.ValueString()) req.Data.SetAttributes(*attributes) return req, diags diff --git a/datadog/tests/cassettes/TestAccRumMetricAttributes.freeze b/datadog/tests/cassettes/TestAccRumMetricAttributes.freeze index 5ff118de3..40c5aca43 100644 --- a/datadog/tests/cassettes/TestAccRumMetricAttributes.freeze +++ b/datadog/tests/cassettes/TestAccRumMetricAttributes.freeze @@ -1 +1 @@ -2024-11-13T14:53:37.123281+01:00 \ No newline at end of file +2024-11-14T08:43:39.339296+01:00 \ No newline at end of file diff --git a/datadog/tests/cassettes/TestAccRumMetricAttributes.yaml b/datadog/tests/cassettes/TestAccRumMetricAttributes.yaml index 3ce7c4b6d..87e24a54d 100644 --- a/datadog/tests/cassettes/TestAccRumMetricAttributes.yaml +++ b/datadog/tests/cassettes/TestAccRumMetricAttributes.yaml @@ -6,14 +6,14 @@ interactions: proto: HTTP/1.1 proto_major: 1 proto_minor: 1 - content_length: 166 + content_length: 162 transfer_encoding: [] trailer: {} host: api.datadoghq.com remote_addr: "" request_uri: "" body: | - {"data":{"attributes":{"compute":{"aggregation_type":"count"},"event_type":"action"},"id":"\"tf_TestAccRumMetricAttributes_local_1731506017\"","type":"rum_metrics"}} + {"data":{"attributes":{"compute":{"aggregation_type":"count"},"event_type":"action"},"id":"tf_TestAccRumMetricAttributes_local_1731570219","type":"rum_metrics"}} form: {} headers: Accept: @@ -30,13 +30,13 @@ interactions: trailer: {} content_length: 175 uncompressed: false - body: '{"data":{"id":"tf_TestAccRumMetricAttributes_local_1731506017","type":"rum_metrics","attributes":{"compute":{"aggregation_type":"count"},"event_type":"action","group_by":[]}}}' + body: '{"data":{"id":"tf_TestAccRumMetricAttributes_local_1731570219","type":"rum_metrics","attributes":{"compute":{"aggregation_type":"count"},"event_type":"action","group_by":[]}}}' headers: Content-Type: - application/vnd.api+json status: 201 Created code: 201 - duration: 815.741958ms + duration: 284.684291ms - id: 1 request: proto: HTTP/1.1 @@ -53,7 +53,7 @@ interactions: headers: Accept: - application/json - url: https://api.datadoghq.com/api/v2/rum/config/metrics/tf_TestAccRumMetricAttributes_local_1731506017 + url: https://api.datadoghq.com/api/v2/rum/config/metrics/tf_TestAccRumMetricAttributes_local_1731570219 method: GET response: proto: HTTP/2.0 @@ -63,13 +63,13 @@ interactions: trailer: {} content_length: 175 uncompressed: false - body: '{"data":{"id":"tf_TestAccRumMetricAttributes_local_1731506017","type":"rum_metrics","attributes":{"compute":{"aggregation_type":"count"},"event_type":"action","group_by":[]}}}' + body: '{"data":{"id":"tf_TestAccRumMetricAttributes_local_1731570219","type":"rum_metrics","attributes":{"compute":{"aggregation_type":"count"},"event_type":"action","group_by":[]}}}' headers: Content-Type: - application/vnd.api+json status: 200 OK code: 200 - duration: 109.067958ms + duration: 110.622375ms - id: 2 request: proto: HTTP/1.1 @@ -86,7 +86,7 @@ interactions: headers: Accept: - '*/*' - url: https://api.datadoghq.com/api/v2/rum/config/metrics/tf_TestAccRumMetricAttributes_local_1731506017 + url: https://api.datadoghq.com/api/v2/rum/config/metrics/tf_TestAccRumMetricAttributes_local_1731570219 method: DELETE response: proto: HTTP/2.0 @@ -100,20 +100,20 @@ interactions: headers: {} status: 204 No Content code: 204 - duration: 117.488125ms + duration: 106.971625ms - id: 3 request: proto: HTTP/1.1 proto_major: 1 proto_minor: 1 - content_length: 219 + content_length: 215 transfer_encoding: [] trailer: {} host: api.datadoghq.com remote_addr: "" request_uri: "" body: | - {"data":{"attributes":{"compute":{"aggregation_type":"distribution","include_percentiles":true,"path":"@duration"},"event_type":"action"},"id":"\"tf_TestAccRumMetricAttributes_local_1731506017\"","type":"rum_metrics"}} + {"data":{"attributes":{"compute":{"aggregation_type":"distribution","include_percentiles":true,"path":"@duration"},"event_type":"action"},"id":"tf_TestAccRumMetricAttributes_local_1731570219","type":"rum_metrics"}} form: {} headers: Accept: @@ -130,13 +130,13 @@ interactions: trailer: {} content_length: 228 uncompressed: false - body: '{"data":{"id":"tf_TestAccRumMetricAttributes_local_1731506017","type":"rum_metrics","attributes":{"compute":{"aggregation_type":"distribution","include_percentiles":true,"path":"@duration"},"event_type":"action","group_by":[]}}}' + body: '{"data":{"id":"tf_TestAccRumMetricAttributes_local_1731570219","type":"rum_metrics","attributes":{"compute":{"aggregation_type":"distribution","include_percentiles":true,"path":"@duration"},"event_type":"action","group_by":[]}}}' headers: Content-Type: - application/vnd.api+json status: 201 Created code: 201 - duration: 1.02972725s + duration: 169.534458ms - id: 4 request: proto: HTTP/1.1 @@ -153,7 +153,7 @@ interactions: headers: Accept: - application/json - url: https://api.datadoghq.com/api/v2/rum/config/metrics/tf_TestAccRumMetricAttributes_local_1731506017 + url: https://api.datadoghq.com/api/v2/rum/config/metrics/tf_TestAccRumMetricAttributes_local_1731570219 method: GET response: proto: HTTP/2.0 @@ -163,14 +163,116 @@ interactions: trailer: {} content_length: 228 uncompressed: false - body: '{"data":{"id":"tf_TestAccRumMetricAttributes_local_1731506017","type":"rum_metrics","attributes":{"compute":{"aggregation_type":"distribution","include_percentiles":true,"path":"@duration"},"event_type":"action","group_by":[]}}}' + body: '{"data":{"id":"tf_TestAccRumMetricAttributes_local_1731570219","type":"rum_metrics","attributes":{"compute":{"aggregation_type":"distribution","include_percentiles":true,"path":"@duration"},"event_type":"action","group_by":[]}}}' headers: Content-Type: - application/vnd.api+json status: 200 OK code: 200 - duration: 108.842709ms + duration: 101.855583ms - id: 5 + request: + proto: HTTP/1.1 + proto_major: 1 + proto_minor: 1 + content_length: 0 + transfer_encoding: [] + trailer: {} + host: api.datadoghq.com + remote_addr: "" + request_uri: "" + body: "" + form: {} + headers: + Accept: + - application/json + url: https://api.datadoghq.com/api/v2/rum/config/metrics/tf_TestAccRumMetricAttributes_local_1731570219 + method: GET + response: + proto: HTTP/2.0 + proto_major: 2 + proto_minor: 0 + transfer_encoding: [] + trailer: {} + content_length: 228 + uncompressed: false + body: '{"data":{"id":"tf_TestAccRumMetricAttributes_local_1731570219","type":"rum_metrics","attributes":{"compute":{"aggregation_type":"distribution","include_percentiles":true,"path":"@duration"},"event_type":"action","group_by":[]}}}' + headers: + Content-Type: + - application/vnd.api+json + status: 200 OK + code: 200 + duration: 103.168042ms + - id: 6 + request: + proto: HTTP/1.1 + proto_major: 1 + proto_minor: 1 + content_length: 141 + transfer_encoding: [] + trailer: {} + host: api.datadoghq.com + remote_addr: "" + request_uri: "" + body: | + {"data":{"attributes":{"compute":{"include_percentiles":false}},"id":"tf_TestAccRumMetricAttributes_local_1731570219","type":"rum_metrics"}} + form: {} + headers: + Accept: + - application/json + Content-Type: + - application/json + url: https://api.datadoghq.com/api/v2/rum/config/metrics/tf_TestAccRumMetricAttributes_local_1731570219 + method: PATCH + response: + proto: HTTP/2.0 + proto_major: 2 + proto_minor: 0 + transfer_encoding: [] + trailer: {} + content_length: 229 + uncompressed: false + body: '{"data":{"id":"tf_TestAccRumMetricAttributes_local_1731570219","type":"rum_metrics","attributes":{"compute":{"aggregation_type":"distribution","include_percentiles":false,"path":"@duration"},"event_type":"action","group_by":[]}}}' + headers: + Content-Type: + - application/vnd.api+json + status: 200 OK + code: 200 + duration: 198.737833ms + - id: 7 + request: + proto: HTTP/1.1 + proto_major: 1 + proto_minor: 1 + content_length: 0 + transfer_encoding: [] + trailer: {} + host: api.datadoghq.com + remote_addr: "" + request_uri: "" + body: "" + form: {} + headers: + Accept: + - application/json + url: https://api.datadoghq.com/api/v2/rum/config/metrics/tf_TestAccRumMetricAttributes_local_1731570219 + method: GET + response: + proto: HTTP/2.0 + proto_major: 2 + proto_minor: 0 + transfer_encoding: [] + trailer: {} + content_length: 229 + uncompressed: false + body: '{"data":{"id":"tf_TestAccRumMetricAttributes_local_1731570219","type":"rum_metrics","attributes":{"compute":{"aggregation_type":"distribution","include_percentiles":false,"path":"@duration"},"event_type":"action","group_by":[]}}}' + headers: + Content-Type: + - application/vnd.api+json + status: 200 OK + code: 200 + duration: 105.835417ms + - id: 8 request: proto: HTTP/1.1 proto_major: 1 @@ -186,7 +288,7 @@ interactions: headers: Accept: - '*/*' - url: https://api.datadoghq.com/api/v2/rum/config/metrics/tf_TestAccRumMetricAttributes_local_1731506017 + url: https://api.datadoghq.com/api/v2/rum/config/metrics/tf_TestAccRumMetricAttributes_local_1731570219 method: DELETE response: proto: HTTP/2.0 @@ -200,20 +302,20 @@ interactions: headers: {} status: 204 No Content code: 204 - duration: 112.006667ms - - id: 6 + duration: 103.626958ms + - id: 9 request: proto: HTTP/1.1 proto_major: 1 proto_minor: 1 - content_length: 203 + content_length: 199 transfer_encoding: [] trailer: {} host: api.datadoghq.com remote_addr: "" request_uri: "" body: | - {"data":{"attributes":{"compute":{"aggregation_type":"count"},"event_type":"action","filter":{"query":"@service:web-ui"}},"id":"\"tf_TestAccRumMetricAttributes_local_1731506017\"","type":"rum_metrics"}} + {"data":{"attributes":{"compute":{"aggregation_type":"count"},"event_type":"action","filter":{"query":"@service:web-ui"}},"id":"tf_TestAccRumMetricAttributes_local_1731570219","type":"rum_metrics"}} form: {} headers: Accept: @@ -230,14 +332,14 @@ interactions: trailer: {} content_length: 212 uncompressed: false - body: '{"data":{"id":"tf_TestAccRumMetricAttributes_local_1731506017","type":"rum_metrics","attributes":{"compute":{"aggregation_type":"count"},"event_type":"action","filter":{"query":"@service:web-ui"},"group_by":[]}}}' + body: '{"data":{"id":"tf_TestAccRumMetricAttributes_local_1731570219","type":"rum_metrics","attributes":{"compute":{"aggregation_type":"count"},"event_type":"action","filter":{"query":"@service:web-ui"},"group_by":[]}}}' headers: Content-Type: - application/vnd.api+json status: 201 Created code: 201 - duration: 247.393ms - - id: 7 + duration: 295.008292ms + - id: 10 request: proto: HTTP/1.1 proto_major: 1 @@ -253,7 +355,7 @@ interactions: headers: Accept: - application/json - url: https://api.datadoghq.com/api/v2/rum/config/metrics/tf_TestAccRumMetricAttributes_local_1731506017 + url: https://api.datadoghq.com/api/v2/rum/config/metrics/tf_TestAccRumMetricAttributes_local_1731570219 method: GET response: proto: HTTP/2.0 @@ -263,14 +365,116 @@ interactions: trailer: {} content_length: 212 uncompressed: false - body: '{"data":{"id":"tf_TestAccRumMetricAttributes_local_1731506017","type":"rum_metrics","attributes":{"compute":{"aggregation_type":"count"},"event_type":"action","filter":{"query":"@service:web-ui"},"group_by":[]}}}' + body: '{"data":{"id":"tf_TestAccRumMetricAttributes_local_1731570219","type":"rum_metrics","attributes":{"compute":{"aggregation_type":"count"},"event_type":"action","filter":{"query":"@service:web-ui"},"group_by":[]}}}' headers: Content-Type: - application/vnd.api+json status: 200 OK code: 200 - duration: 107.427541ms - - id: 8 + duration: 103.364625ms + - id: 11 + request: + proto: HTTP/1.1 + proto_major: 1 + proto_minor: 1 + content_length: 0 + transfer_encoding: [] + trailer: {} + host: api.datadoghq.com + remote_addr: "" + request_uri: "" + body: "" + form: {} + headers: + Accept: + - application/json + url: https://api.datadoghq.com/api/v2/rum/config/metrics/tf_TestAccRumMetricAttributes_local_1731570219 + method: GET + response: + proto: HTTP/2.0 + proto_major: 2 + proto_minor: 0 + transfer_encoding: [] + trailer: {} + content_length: 212 + uncompressed: false + body: '{"data":{"id":"tf_TestAccRumMetricAttributes_local_1731570219","type":"rum_metrics","attributes":{"compute":{"aggregation_type":"count"},"event_type":"action","filter":{"query":"@service:web-ui"},"group_by":[]}}}' + headers: + Content-Type: + - application/vnd.api+json + status: 200 OK + code: 200 + duration: 102.999625ms + - id: 12 + request: + proto: HTTP/1.1 + proto_major: 1 + proto_minor: 1 + content_length: 160 + transfer_encoding: [] + trailer: {} + host: api.datadoghq.com + remote_addr: "" + request_uri: "" + body: | + {"data":{"attributes":{"compute":{},"filter":{"query":"@service:another-service"}},"id":"tf_TestAccRumMetricAttributes_local_1731570219","type":"rum_metrics"}} + form: {} + headers: + Accept: + - application/json + Content-Type: + - application/json + url: https://api.datadoghq.com/api/v2/rum/config/metrics/tf_TestAccRumMetricAttributes_local_1731570219 + method: PATCH + response: + proto: HTTP/2.0 + proto_major: 2 + proto_minor: 0 + transfer_encoding: [] + trailer: {} + content_length: 221 + uncompressed: false + body: '{"data":{"id":"tf_TestAccRumMetricAttributes_local_1731570219","type":"rum_metrics","attributes":{"compute":{"aggregation_type":"count"},"event_type":"action","filter":{"query":"@service:another-service"},"group_by":[]}}}' + headers: + Content-Type: + - application/vnd.api+json + status: 200 OK + code: 200 + duration: 113.463959ms + - id: 13 + request: + proto: HTTP/1.1 + proto_major: 1 + proto_minor: 1 + content_length: 0 + transfer_encoding: [] + trailer: {} + host: api.datadoghq.com + remote_addr: "" + request_uri: "" + body: "" + form: {} + headers: + Accept: + - application/json + url: https://api.datadoghq.com/api/v2/rum/config/metrics/tf_TestAccRumMetricAttributes_local_1731570219 + method: GET + response: + proto: HTTP/2.0 + proto_major: 2 + proto_minor: 0 + transfer_encoding: [] + trailer: {} + content_length: 221 + uncompressed: false + body: '{"data":{"id":"tf_TestAccRumMetricAttributes_local_1731570219","type":"rum_metrics","attributes":{"compute":{"aggregation_type":"count"},"event_type":"action","filter":{"query":"@service:another-service"},"group_by":[]}}}' + headers: + Content-Type: + - application/vnd.api+json + status: 200 OK + code: 200 + duration: 105.07ms + - id: 14 request: proto: HTTP/1.1 proto_major: 1 @@ -286,7 +490,7 @@ interactions: headers: Accept: - '*/*' - url: https://api.datadoghq.com/api/v2/rum/config/metrics/tf_TestAccRumMetricAttributes_local_1731506017 + url: https://api.datadoghq.com/api/v2/rum/config/metrics/tf_TestAccRumMetricAttributes_local_1731570219 method: DELETE response: proto: HTTP/2.0 @@ -300,20 +504,20 @@ interactions: headers: {} status: 204 No Content code: 204 - duration: 107.245458ms - - id: 9 + duration: 105.244208ms + - id: 15 request: proto: HTTP/1.1 proto_major: 1 proto_minor: 1 - content_length: 251 + content_length: 247 transfer_encoding: [] trailer: {} host: api.datadoghq.com remote_addr: "" request_uri: "" body: | - {"data":{"attributes":{"compute":{"aggregation_type":"count"},"event_type":"action","group_by":[{"path":"@os","tag_name":"os"},{"path":"@service","tag_name":"service"}]},"id":"\"tf_TestAccRumMetricAttributes_local_1731506017\"","type":"rum_metrics"}} + {"data":{"attributes":{"compute":{"aggregation_type":"count"},"event_type":"action","group_by":[{"path":"@os","tag_name":"os"},{"path":"@service","tag_name":"service"}]},"id":"tf_TestAccRumMetricAttributes_local_1731570219","type":"rum_metrics"}} form: {} headers: Accept: @@ -330,14 +534,14 @@ interactions: trailer: {} content_length: 246 uncompressed: false - body: '{"data":{"id":"tf_TestAccRumMetricAttributes_local_1731506017","type":"rum_metrics","attributes":{"compute":{"aggregation_type":"count"},"event_type":"action","group_by":[{"path":"@os","tag_name":"os"},{"path":"@service","tag_name":"service"}]}}}' + body: '{"data":{"id":"tf_TestAccRumMetricAttributes_local_1731570219","type":"rum_metrics","attributes":{"compute":{"aggregation_type":"count"},"event_type":"action","group_by":[{"path":"@os","tag_name":"os"},{"path":"@service","tag_name":"service"}]}}}' headers: Content-Type: - application/vnd.api+json status: 201 Created code: 201 - duration: 550.922458ms - - id: 10 + duration: 173.423208ms + - id: 16 request: proto: HTTP/1.1 proto_major: 1 @@ -353,7 +557,7 @@ interactions: headers: Accept: - application/json - url: https://api.datadoghq.com/api/v2/rum/config/metrics/tf_TestAccRumMetricAttributes_local_1731506017 + url: https://api.datadoghq.com/api/v2/rum/config/metrics/tf_TestAccRumMetricAttributes_local_1731570219 method: GET response: proto: HTTP/2.0 @@ -363,14 +567,116 @@ interactions: trailer: {} content_length: 246 uncompressed: false - body: '{"data":{"id":"tf_TestAccRumMetricAttributes_local_1731506017","type":"rum_metrics","attributes":{"compute":{"aggregation_type":"count"},"event_type":"action","group_by":[{"path":"@os","tag_name":"os"},{"path":"@service","tag_name":"service"}]}}}' + body: '{"data":{"id":"tf_TestAccRumMetricAttributes_local_1731570219","type":"rum_metrics","attributes":{"compute":{"aggregation_type":"count"},"event_type":"action","group_by":[{"path":"@os","tag_name":"os"},{"path":"@service","tag_name":"service"}]}}}' headers: Content-Type: - application/vnd.api+json status: 200 OK code: 200 - duration: 107.373583ms - - id: 11 + duration: 101.0235ms + - id: 17 + request: + proto: HTTP/1.1 + proto_major: 1 + proto_minor: 1 + content_length: 0 + transfer_encoding: [] + trailer: {} + host: api.datadoghq.com + remote_addr: "" + request_uri: "" + body: "" + form: {} + headers: + Accept: + - application/json + url: https://api.datadoghq.com/api/v2/rum/config/metrics/tf_TestAccRumMetricAttributes_local_1731570219 + method: GET + response: + proto: HTTP/2.0 + proto_major: 2 + proto_minor: 0 + transfer_encoding: [] + trailer: {} + content_length: 246 + uncompressed: false + body: '{"data":{"id":"tf_TestAccRumMetricAttributes_local_1731570219","type":"rum_metrics","attributes":{"compute":{"aggregation_type":"count"},"event_type":"action","group_by":[{"path":"@os","tag_name":"os"},{"path":"@service","tag_name":"service"}]}}}' + headers: + Content-Type: + - application/vnd.api+json + status: 200 OK + code: 200 + duration: 103.437333ms + - id: 18 + request: + proto: HTTP/1.1 + proto_major: 1 + proto_minor: 1 + content_length: 276 + transfer_encoding: [] + trailer: {} + host: api.datadoghq.com + remote_addr: "" + request_uri: "" + body: | + {"data":{"attributes":{"compute":{},"group_by":[{"path":"@os","tag_name":"os"},{"path":"@os.version.major","tag_name":"os_version_major"},{"path":"@os.version.minor","tag_name":"os_version_minor"}]},"id":"tf_TestAccRumMetricAttributes_local_1731570219","type":"rum_metrics"}} + form: {} + headers: + Accept: + - application/json + Content-Type: + - application/json + url: https://api.datadoghq.com/api/v2/rum/config/metrics/tf_TestAccRumMetricAttributes_local_1731570219 + method: PATCH + response: + proto: HTTP/2.0 + proto_major: 2 + proto_minor: 0 + transfer_encoding: [] + trailer: {} + content_length: 323 + uncompressed: false + body: '{"data":{"id":"tf_TestAccRumMetricAttributes_local_1731570219","type":"rum_metrics","attributes":{"compute":{"aggregation_type":"count"},"event_type":"action","group_by":[{"path":"@os","tag_name":"os"},{"path":"@os.version.major","tag_name":"os_version_major"},{"path":"@os.version.minor","tag_name":"os_version_minor"}]}}}' + headers: + Content-Type: + - application/vnd.api+json + status: 200 OK + code: 200 + duration: 167.486542ms + - id: 19 + request: + proto: HTTP/1.1 + proto_major: 1 + proto_minor: 1 + content_length: 0 + transfer_encoding: [] + trailer: {} + host: api.datadoghq.com + remote_addr: "" + request_uri: "" + body: "" + form: {} + headers: + Accept: + - application/json + url: https://api.datadoghq.com/api/v2/rum/config/metrics/tf_TestAccRumMetricAttributes_local_1731570219 + method: GET + response: + proto: HTTP/2.0 + proto_major: 2 + proto_minor: 0 + transfer_encoding: [] + trailer: {} + content_length: 323 + uncompressed: false + body: '{"data":{"id":"tf_TestAccRumMetricAttributes_local_1731570219","type":"rum_metrics","attributes":{"compute":{"aggregation_type":"count"},"event_type":"action","group_by":[{"path":"@os","tag_name":"os"},{"path":"@os.version.major","tag_name":"os_version_major"},{"path":"@os.version.minor","tag_name":"os_version_minor"}]}}}' + headers: + Content-Type: + - application/vnd.api+json + status: 200 OK + code: 200 + duration: 102.668125ms + - id: 20 request: proto: HTTP/1.1 proto_major: 1 @@ -386,7 +692,7 @@ interactions: headers: Accept: - '*/*' - url: https://api.datadoghq.com/api/v2/rum/config/metrics/tf_TestAccRumMetricAttributes_local_1731506017 + url: https://api.datadoghq.com/api/v2/rum/config/metrics/tf_TestAccRumMetricAttributes_local_1731570219 method: DELETE response: proto: HTTP/2.0 @@ -400,4 +706,4 @@ interactions: headers: {} status: 204 No Content code: 204 - duration: 108.528417ms + duration: 105.208958ms diff --git a/datadog/tests/cassettes/TestAccRumMetricImport.freeze b/datadog/tests/cassettes/TestAccRumMetricImport.freeze index 05e44395d..978a2cd7d 100644 --- a/datadog/tests/cassettes/TestAccRumMetricImport.freeze +++ b/datadog/tests/cassettes/TestAccRumMetricImport.freeze @@ -1 +1 @@ -2024-11-13T14:53:37.123287+01:00 \ No newline at end of file +2024-11-14T08:43:39.33944+01:00 \ No newline at end of file diff --git a/datadog/tests/cassettes/TestAccRumMetricImport.yaml b/datadog/tests/cassettes/TestAccRumMetricImport.yaml index 6a2f59a8b..99a541846 100644 --- a/datadog/tests/cassettes/TestAccRumMetricImport.yaml +++ b/datadog/tests/cassettes/TestAccRumMetricImport.yaml @@ -6,14 +6,14 @@ interactions: proto: HTTP/1.1 proto_major: 1 proto_minor: 1 - content_length: 162 + content_length: 158 transfer_encoding: [] trailer: {} host: api.datadoghq.com remote_addr: "" request_uri: "" body: | - {"data":{"attributes":{"compute":{"aggregation_type":"count"},"event_type":"action"},"id":"\"tf_TestAccRumMetricImport_local_1731506017\"","type":"rum_metrics"}} + {"data":{"attributes":{"compute":{"aggregation_type":"count"},"event_type":"action"},"id":"tf_TestAccRumMetricImport_local_1731570219","type":"rum_metrics"}} form: {} headers: Accept: @@ -30,13 +30,13 @@ interactions: trailer: {} content_length: 171 uncompressed: false - body: '{"data":{"id":"tf_TestAccRumMetricImport_local_1731506017","type":"rum_metrics","attributes":{"compute":{"aggregation_type":"count"},"event_type":"action","group_by":[]}}}' + body: '{"data":{"id":"tf_TestAccRumMetricImport_local_1731570219","type":"rum_metrics","attributes":{"compute":{"aggregation_type":"count"},"event_type":"action","group_by":[]}}}' headers: Content-Type: - application/vnd.api+json status: 201 Created code: 201 - duration: 707.791ms + duration: 303.473833ms - id: 1 request: proto: HTTP/1.1 @@ -53,7 +53,7 @@ interactions: headers: Accept: - application/json - url: https://api.datadoghq.com/api/v2/rum/config/metrics/tf_TestAccRumMetricImport_local_1731506017 + url: https://api.datadoghq.com/api/v2/rum/config/metrics/tf_TestAccRumMetricImport_local_1731570219 method: GET response: proto: HTTP/2.0 @@ -63,13 +63,13 @@ interactions: trailer: {} content_length: 171 uncompressed: false - body: '{"data":{"id":"tf_TestAccRumMetricImport_local_1731506017","type":"rum_metrics","attributes":{"compute":{"aggregation_type":"count"},"event_type":"action","group_by":[]}}}' + body: '{"data":{"id":"tf_TestAccRumMetricImport_local_1731570219","type":"rum_metrics","attributes":{"compute":{"aggregation_type":"count"},"event_type":"action","group_by":[]}}}' headers: Content-Type: - application/vnd.api+json status: 200 OK code: 200 - duration: 108.442334ms + duration: 120.268708ms - id: 2 request: proto: HTTP/1.1 @@ -86,7 +86,7 @@ interactions: headers: Accept: - application/json - url: https://api.datadoghq.com/api/v2/rum/config/metrics/tf_TestAccRumMetricImport_local_1731506017 + url: https://api.datadoghq.com/api/v2/rum/config/metrics/tf_TestAccRumMetricImport_local_1731570219 method: GET response: proto: HTTP/2.0 @@ -96,13 +96,13 @@ interactions: trailer: {} content_length: 171 uncompressed: false - body: '{"data":{"id":"tf_TestAccRumMetricImport_local_1731506017","type":"rum_metrics","attributes":{"compute":{"aggregation_type":"count"},"event_type":"action","group_by":[]}}}' + body: '{"data":{"id":"tf_TestAccRumMetricImport_local_1731570219","type":"rum_metrics","attributes":{"compute":{"aggregation_type":"count"},"event_type":"action","group_by":[]}}}' headers: Content-Type: - application/vnd.api+json status: 200 OK code: 200 - duration: 109.190917ms + duration: 107.598417ms - id: 3 request: proto: HTTP/1.1 @@ -119,7 +119,7 @@ interactions: headers: Accept: - '*/*' - url: https://api.datadoghq.com/api/v2/rum/config/metrics/tf_TestAccRumMetricImport_local_1731506017 + url: https://api.datadoghq.com/api/v2/rum/config/metrics/tf_TestAccRumMetricImport_local_1731570219 method: DELETE response: proto: HTTP/2.0 @@ -133,4 +133,4 @@ interactions: headers: {} status: 204 No Content code: 204 - duration: 111.724542ms + duration: 107.622958ms diff --git a/datadog/tests/resource_datadog_rum_metric_test.go b/datadog/tests/resource_datadog_rum_metric_test.go index 4f3756aa9..042c132f1 100644 --- a/datadog/tests/resource_datadog_rum_metric_test.go +++ b/datadog/tests/resource_datadog_rum_metric_test.go @@ -19,10 +19,9 @@ func TestAccRumMetricImport(t *testing.T) { ctx, providers, accProviders := testAccFrameworkMuxProviders(context.Background(), t) // The API will currently silently remap - to _, which makes terraform unhappy. This will - // just make the tests pass but this is a real issue. - // Being addressed in https://datadoghq.atlassian.net/browse/RUM-7124. Note that this is - // also an issue for other existing APIs using the same backend (spans metrics and maybe - // logs metrics?). + // just make the tests pass but this is a real issue. It is discussed in + // https://datadoghq.atlassian.net/browse/RUM-7124. Note that this is also the case for + // other existing APIs using the same backend (spans metrics and maybe logs metrics?). uniq := strings.ReplaceAll(uniqueEntityName(ctx, t), "-", "_") resource.Test(t, resource.TestCase{ @@ -84,6 +83,14 @@ func TestAccRumMetricAttributes(t *testing.T) { "datadog_rum_metric.testing_rum_metric", "compute.path", "@duration"), ), }, + { + Config: distributionDatadogRumMetricUpdate(uniq), + Check: resource.ComposeTestCheckFunc( + testAccCheckDatadogSpansMetricExists(providers.frameworkProvider), + resource.TestCheckResourceAttr( + "datadog_rum_metric.testing_rum_metric", "compute.include_percentiles", "false"), + ), + }, }, }) @@ -99,6 +106,14 @@ func TestAccRumMetricAttributes(t *testing.T) { "datadog_rum_metric.testing_rum_metric", "filter.query", "@service:web-ui"), ), }, + { + Config: filterDatadogRumMetricUpdate(uniq), + Check: resource.ComposeTestCheckFunc( + testAccCheckDatadogRumMetricExists(providers.frameworkProvider), + resource.TestCheckResourceAttr( + "datadog_rum_metric.testing_rum_metric", "filter.query", "@service:another-service"), + ), + }, }, }) @@ -108,12 +123,39 @@ func TestAccRumMetricAttributes(t *testing.T) { Steps: []resource.TestStep{ { Config: groupByDatadogRumMetric(uniq), - Check: testAccCheckDatadogRumMetricExists(providers.frameworkProvider), - // resource.ComposeTestCheckFunc( - - // resource.TestCheckResourceAttr( - // "datadog_rum_metric.testing_rum_metric", "group_by.#", "2"), - // ), + Check: resource.ComposeTestCheckFunc( + testAccCheckDatadogRumMetricExists(providers.frameworkProvider), + resource.TestCheckResourceAttr( + "datadog_rum_metric.testing_rum_metric", "group_by.#", "2"), + resource.TestCheckResourceAttr( + "datadog_rum_metric.testing_rum_metric", "group_by.0.path", "@os"), + resource.TestCheckResourceAttr( + "datadog_rum_metric.testing_rum_metric", "group_by.0.tag_name", "os"), + resource.TestCheckResourceAttr( + "datadog_rum_metric.testing_rum_metric", "group_by.1.path", "@service"), + resource.TestCheckResourceAttr( + "datadog_rum_metric.testing_rum_metric", "group_by.1.tag_name", "service"), + ), + }, + { + Config: groupByDatadogRumMetricUpdate(uniq), + Check: resource.ComposeTestCheckFunc( + testAccCheckDatadogRumMetricExists(providers.frameworkProvider), + resource.TestCheckResourceAttr( + "datadog_rum_metric.testing_rum_metric", "group_by.#", "3"), + resource.TestCheckResourceAttr( + "datadog_rum_metric.testing_rum_metric", "group_by.0.path", "@os"), + resource.TestCheckResourceAttr( + "datadog_rum_metric.testing_rum_metric", "group_by.0.tag_name", "os"), + resource.TestCheckResourceAttr( + "datadog_rum_metric.testing_rum_metric", "group_by.1.path", "@os.version.major"), + resource.TestCheckResourceAttr( + "datadog_rum_metric.testing_rum_metric", "group_by.1.tag_name", "os_version_major"), + resource.TestCheckResourceAttr( + "datadog_rum_metric.testing_rum_metric", "group_by.2.path", "@os.version.minor"), + resource.TestCheckResourceAttr( + "datadog_rum_metric.testing_rum_metric", "group_by.2.tag_name", "os_version_minor"), + ), }, }, }) @@ -143,12 +185,14 @@ func distributionDatadogRumMetric(uniq string) string { `, uniq) } -func countDatadogRumMetric(uniq string) string { +func distributionDatadogRumMetricUpdate(uniq string) string { return fmt.Sprintf(`resource "datadog_rum_metric" "testing_rum_metric" { name = %q event_type = "action" compute { - aggregation_type = "count" + aggregation_type = "distribution" + include_percentiles = false + path = "@duration" } } `, uniq) @@ -168,6 +212,20 @@ func filterDatadogRumMetric(uniq string) string { `, uniq) } +func filterDatadogRumMetricUpdate(uniq string) string { + return fmt.Sprintf(`resource "datadog_rum_metric" "testing_rum_metric" { + name = %q + event_type = "action" + compute { + aggregation_type = "count" + } + filter { + query = "@service:another-service" + } + } + `, uniq) +} + func groupByDatadogRumMetric(uniq string) string { // Note: the group_bys are not defined in alphabetical order. This is on purpose to verify // a set behavior rather than a list behavior on the terraform attribute. @@ -189,6 +247,29 @@ func groupByDatadogRumMetric(uniq string) string { `, uniq) } +func groupByDatadogRumMetricUpdate(uniq string) string { + return fmt.Sprintf(`resource "datadog_rum_metric" "testing_rum_metric" { + name = %q + event_type = "action" + compute { + aggregation_type = "count" + } + group_by { + path = "@os" + tag_name = "os" + } + group_by { + path = "@os.version.major" + tag_name = "os_version_major" + } + group_by { + path = "@os.version.minor" + tag_name = "os_version_minor" + } + } + `, uniq) +} + func testAccCheckDatadogRumMetricDestroy(accProvider *fwprovider.FrameworkProvider) func(*terraform.State) error { return func(s *terraform.State) error { apiInstances := accProvider.DatadogApiInstances From cf4c1411df9db04a392567fafce95991ea6a60c7 Mon Sep 17 00:00:00 2001 From: Arthur Hemery Date: Thu, 14 Nov 2024 17:22:44 +0100 Subject: [PATCH 10/10] Update doc --- datadog/fwprovider/resource_datadog_rum_metric.go | 10 +++++----- docs/resources/rum_metric.md | 10 +++++----- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/datadog/fwprovider/resource_datadog_rum_metric.go b/datadog/fwprovider/resource_datadog_rum_metric.go index ba3754c6b..979a040c5 100644 --- a/datadog/fwprovider/resource_datadog_rum_metric.go +++ b/datadog/fwprovider/resource_datadog_rum_metric.go @@ -73,7 +73,7 @@ func (r *rumMetricResource) Schema(_ context.Context, _ resource.SchemaRequest, Description: "Provides a Datadog RumMetric resource. This can be used to create and manage Datadog rum_metric.", Attributes: map[string]schema.Attribute{ "name": schema.StringAttribute{ - Description: "The name of the rum-based metric. This field can't be updated after creation.", + Description: "The name of the RUM-based metric. This field can't be updated after creation.", Required: true, PlanModifiers: []planmodifier.String{ stringplanmodifier.RequiresReplace(), @@ -103,7 +103,7 @@ func (r *rumMetricResource) Schema(_ context.Context, _ resource.SchemaRequest, Optional: true, }, "path": schema.StringAttribute{ - Description: "The path to the value the rum-based metric will aggregate on. Only present when `aggregation_type` is `distribution`.", + Description: "The path to the value the RUM-based metric will aggregate on. Only present when `aggregation_type` is `distribution`.", Optional: true, PlanModifiers: []planmodifier.String{ stringplanmodifier.RequiresReplace(), @@ -114,7 +114,7 @@ func (r *rumMetricResource) Schema(_ context.Context, _ resource.SchemaRequest, "filter": schema.SingleNestedBlock{ Attributes: map[string]schema.Attribute{ "query": schema.StringAttribute{ - Description: "The search query - following the RUM search syntax.", + Description: "The search query. Follows RUM search syntax.", Optional: true, }, }, @@ -123,11 +123,11 @@ func (r *rumMetricResource) Schema(_ context.Context, _ resource.SchemaRequest, NestedObject: schema.NestedBlockObject{ Attributes: map[string]schema.Attribute{ "path": schema.StringAttribute{ - Description: "The path to the value the rum-based metric will be aggregated over.", + Description: "The path to the value the RUM-based metric will be aggregated over.", Optional: true, }, "tag_name": schema.StringAttribute{ - Description: "Eventual name of the tag that gets created. By default, `path` is used as the tag name.", + Description: "Name of the tag that gets created. By default, `path` is used as the tag name.", Optional: true, }, }, diff --git a/docs/resources/rum_metric.md b/docs/resources/rum_metric.md index 63f2b8531..40997b787 100644 --- a/docs/resources/rum_metric.md +++ b/docs/resources/rum_metric.md @@ -42,7 +42,7 @@ resource "datadog_rum_metric" "testing_rum_metric" { ### Required - `event_type` (String) The type of RUM events to filter on. -- `name` (String) The name of the rum-based metric. This field can't be updated after creation. +- `name` (String) The name of the RUM-based metric. This field can't be updated after creation. ### Optional @@ -65,7 +65,7 @@ Required: Optional: - `include_percentiles` (Boolean) Toggle to include or exclude percentile aggregations for distribution metrics. Only present when `aggregation_type` is `distribution`. -- `path` (String) The path to the value the rum-based metric will aggregate on. Only present when `aggregation_type` is `distribution`. +- `path` (String) The path to the value the RUM-based metric will aggregate on. Only present when `aggregation_type` is `distribution`. @@ -73,7 +73,7 @@ Optional: Optional: -- `query` (String) The search query - following the RUM search syntax. +- `query` (String) The search query. Follows RUM search syntax. @@ -81,8 +81,8 @@ Optional: Optional: -- `path` (String) The path to the value the rum-based metric will be aggregated over. -- `tag_name` (String) Eventual name of the tag that gets created. By default, `path` is used as the tag name. +- `path` (String) The path to the value the RUM-based metric will be aggregated over. +- `tag_name` (String) Name of the tag that gets created. By default, `path` is used as the tag name.