diff --git a/datadog/fwprovider/data_source_datadog_metrics.go b/datadog/fwprovider/data_source_datadog_metrics.go new file mode 100644 index 000000000..f3b5187e9 --- /dev/null +++ b/datadog/fwprovider/data_source_datadog_metrics.go @@ -0,0 +1,89 @@ +package fwprovider + +import ( + "context" + "fmt" + "strings" + + "github.com/DataDog/datadog-api-client-go/v2/api/datadogV1" + "github.com/hashicorp/terraform-plugin-framework/datasource" + "github.com/hashicorp/terraform-plugin-framework/datasource/schema" + "github.com/hashicorp/terraform-plugin-framework/types" + + "github.com/terraform-providers/terraform-provider-datadog/datadog/internal/utils" +) + +var ( + _ datasource.DataSource = &datadogMetricsDataSource{} +) + +type datadogMetricsModel struct { + ID types.String `tfsdk:"id"` + Query types.String `tfsdk:"query"` + Metrics types.List `tfsdk:"metrics"` +} + +type datadogMetricsDataSource struct { + Api *datadogV1.MetricsApi + Auth context.Context +} + +func NewDatadogMetricsDataSource() datasource.DataSource { + return &datadogMetricsDataSource{} +} + +func (d *datadogMetricsDataSource) Configure(_ context.Context, request datasource.ConfigureRequest, response *datasource.ConfigureResponse) { + providerData, _ := request.ProviderData.(*FrameworkProvider) + d.Api = providerData.DatadogApiInstances.GetMetricsApiV1() + d.Auth = providerData.Auth +} + +func (d *datadogMetricsDataSource) Metadata(_ context.Context, req datasource.MetadataRequest, resp *datasource.MetadataResponse) { + resp.TypeName = "metrics" +} + +func (d *datadogMetricsDataSource) Schema(_ context.Context, _ datasource.SchemaRequest, resp *datasource.SchemaResponse) { + resp.Schema = schema.Schema{ + Description: "Use this data source to list metrics for use in other resources.", + Attributes: map[string]schema.Attribute{ + "id": utils.ResourceIDAttribute(), + "query": schema.StringAttribute{ + Description: "The search query to use when listing metrics.", + Required: true, + }, + // Computed values + "metrics": schema.ListAttribute{ + Description: "The metrics returned by the search query.", + Computed: true, + ElementType: types.StringType, + }, + }, + } +} + +func (d *datadogMetricsDataSource) Read(ctx context.Context, req datasource.ReadRequest, resp *datasource.ReadResponse) { + var state datadogMetricsModel + + resp.Diagnostics.Append(req.Config.Get(ctx, &state)...) + if resp.Diagnostics.HasError() { + return + } + ddResp, _, err := d.Api.ListMetrics(d.Auth, state.Query.ValueString()) + if err != nil { + resp.Diagnostics.Append(utils.FrameworkErrorDiag(err, "error listing metrics")) + return + } + + results := ddResp.GetResults() + metrics := results.GetMetrics() + + d.updateState(ctx, &state, metrics) + resp.Diagnostics.Append(resp.State.Set(ctx, &state)...) +} + +func (d *datadogMetricsDataSource) updateState(ctx context.Context, state *datadogMetricsModel, metrics []string) { + hashingData := fmt.Sprintf("%s:%s", state.Query.ValueString(), strings.Join(metrics, ":")) + + state.ID = types.StringValue(utils.ConvertToSha256(hashingData)) + state.Metrics, _ = types.ListValueFrom(ctx, types.StringType, metrics) +} diff --git a/datadog/fwprovider/framework_provider.go b/datadog/fwprovider/framework_provider.go index 340fdebb8..6b1bfc70e 100644 --- a/datadog/fwprovider/framework_provider.go +++ b/datadog/fwprovider/framework_provider.go @@ -120,6 +120,7 @@ var Datasources = []func() datasource.DataSource{ NewDatadogMetricActiveTagsAndAggregationsDataSource, NewDatadogMetricMetadataDataSource, NewDatadogMetricTagsDataSource, + NewDatadogMetricsDataSource, NewDatadogPowerpackDataSource, NewDatadogServiceAccountDatasource, NewDatadogSoftwareCatalogDataSource, diff --git a/datadog/tests/cassettes/TestAccDatadogMetricsDatasource.freeze b/datadog/tests/cassettes/TestAccDatadogMetricsDatasource.freeze new file mode 100644 index 000000000..cec0a5209 --- /dev/null +++ b/datadog/tests/cassettes/TestAccDatadogMetricsDatasource.freeze @@ -0,0 +1 @@ +2025-09-06T06:43:56.810887-04:00 \ No newline at end of file diff --git a/datadog/tests/cassettes/TestAccDatadogMetricsDatasource.yaml b/datadog/tests/cassettes/TestAccDatadogMetricsDatasource.yaml new file mode 100644 index 000000000..57075f2e0 --- /dev/null +++ b/datadog/tests/cassettes/TestAccDatadogMetricsDatasource.yaml @@ -0,0 +1,108 @@ +--- +version: 2 +interactions: + - id: 0 + 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/v1/search?q=foo. + method: GET + response: + proto: HTTP/1.1 + proto_major: 1 + proto_minor: 1 + transfer_encoding: + - chunked + trailer: {} + content_length: -1 + uncompressed: true + body: | + {"results":{"metrics":["foo.bar","foo.baz"],"hosts":[]}} + headers: + Content-Type: + - application/json + status: 200 OK + code: 200 + duration: 237.101791ms + - id: 1 + 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/v1/search?q=foo. + method: GET + response: + proto: HTTP/1.1 + proto_major: 1 + proto_minor: 1 + transfer_encoding: + - chunked + trailer: {} + content_length: -1 + uncompressed: true + body: | + {"results":{"metrics":["foo.bar","foo.baz"],"hosts":[]}} + headers: + Content-Type: + - application/json + status: 200 OK + code: 200 + duration: 237.101791ms + - id: 2 + 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/v1/search?q=foo. + method: GET + response: + proto: HTTP/1.1 + proto_major: 1 + proto_minor: 1 + transfer_encoding: + - chunked + trailer: {} + content_length: -1 + uncompressed: true + body: | + {"results":{"metrics":["foo.bar","foo.baz"],"hosts":[]}} + headers: + Content-Type: + - application/json + status: 200 OK + code: 200 + duration: 237.101791ms diff --git a/datadog/tests/data_source_datadog_metrics_test.go b/datadog/tests/data_source_datadog_metrics_test.go new file mode 100644 index 000000000..0fa004c06 --- /dev/null +++ b/datadog/tests/data_source_datadog_metrics_test.go @@ -0,0 +1,38 @@ +package test + +import ( + "context" + "fmt" + "testing" + + "github.com/hashicorp/terraform-plugin-testing/helper/resource" +) + +func TestAccDatadogMetricsDatasource(t *testing.T) { + t.Parallel() + _, _, accProviders := testAccFrameworkMuxProviders(context.Background(), t) + query := "foo." + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + ProtoV5ProviderFactories: accProviders, + Steps: []resource.TestStep{ + { + Config: testAccDatasourceMetricsConfig(query), + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr("data.datadog_metrics.foo", "query", query), + resource.TestCheckResourceAttr("data.datadog_metrics.foo", "metrics.0", "foo.bar"), + resource.TestCheckResourceAttr("data.datadog_metrics.foo", "metrics.1", "foo.baz"), + ), + }, + }, + }) +} + +func testAccDatasourceMetricsConfig(query string) string { + return fmt.Sprintf(` +data "datadog_metrics" "foo" { + query = "%s" +} +`, query) +} diff --git a/datadog/tests/provider_test.go b/datadog/tests/provider_test.go index 4c6533cb9..6b6ff84c4 100644 --- a/datadog/tests/provider_test.go +++ b/datadog/tests/provider_test.go @@ -82,6 +82,7 @@ var testFiles2EndpointTags = map[string]string{ "tests/data_source_datadog_metric_active_tags_and_aggregations_test": "metrics", "tests/data_source_datadog_metric_metadata_test": "metrics", "tests/data_source_datadog_metric_tags_test": "metrics", + "tests/data_source_datadog_metrics_test": "metrics", "tests/data_source_datadog_monitor_test": "monitors", "tests/data_source_datadog_monitors_test": "monitors", "tests/data_source_datadog_permissions_test": "permissions", diff --git a/docs/data-sources/metrics.md b/docs/data-sources/metrics.md new file mode 100644 index 000000000..a22d5ec0a --- /dev/null +++ b/docs/data-sources/metrics.md @@ -0,0 +1,25 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "datadog_metrics Data Source - terraform-provider-datadog" +subcategory: "" +description: |- + Use this data source to list metrics for use in other resources. +--- + +# datadog_metrics (Data Source) + +Use this data source to list metrics for use in other resources. + + + + +## Schema + +### Required + +- `query` (String) The search query to use when listing metrics. + +### Read-Only + +- `id` (String) The ID of this resource. +- `metrics` (List of String) The metrics returned by the search query.