Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
51 changes: 27 additions & 24 deletions datadog/resource_datadog_metric_tag_configuration.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,9 @@ func resourceDatadogMetricTagConfiguration() *schema.Resource {
oldAggrs, newAggrs := diff.GetChange("aggregations")
metricType, metricTypeOk := diff.GetOkExists("metric_type")
tags, _ := diff.GetOkExists("tags")
excludeTagsMode, _ := diff.GetOkExists("exclude_tags_mode")
excludeTagsMode, excludeTagsModeOk := diff.GetOkExists("exclude_tags_mode")

if excludeTagsMode.(bool) && len(tags.(*schema.Set).List()) == 0 {
if excludeTagsModeOk && excludeTagsMode.(bool) && len(tags.(*schema.Set).List()) == 0 {
return fmt.Errorf("cannot use exclude_tags_mode without configuring any tags")
}

Expand Down Expand Up @@ -126,10 +126,9 @@ func resourceDatadogMetricTagConfiguration() *schema.Resource {
},
},
"exclude_tags_mode": {
Description: "Toggle to include/exclude tags as queryable for your metric. Can only be applied to metrics that have one or more tags configured.",
Description: "Toggle to include/exclude tags as queryable for your metric. Can only be applied to metrics that have one or more tags configured. If not set, the metric will allow all tags.",
Type: schema.TypeBool,
Optional: true,
Default: false,
},
}
},
Expand Down Expand Up @@ -185,14 +184,14 @@ func buildDatadogMetricTagConfiguration(d *schema.ResourceData) (*datadogV2.Metr
attributes.SetIncludePercentiles(includePercentiles.(bool))
}

excludeTagsMode := d.Get("exclude_tags_mode")

if excludeTagsMode.(bool) && len(stringTags) == 0 {
return nil, fmt.Errorf("cannot use exclude_tags_mode without configuring any tags")
if excludeTagsMode, ok := d.GetOkExists("exclude_tags_mode"); ok {
excludeTagsModeVal := excludeTagsMode.(bool)
if excludeTagsModeVal && len(stringTags) == 0 {
return nil, fmt.Errorf("cannot use exclude_tags_mode without configuring any tags")
}
attributes.SetExcludeTagsMode(excludeTagsModeVal)
}

attributes.SetExcludeTagsMode(excludeTagsMode.(bool))

aggregationsArray, aggregationsFieldSet := d.GetOk("aggregations")
if aggregationsFieldSet {
if *metricType == datadogV2.METRICTAGCONFIGURATIONMETRICTYPES_DISTRIBUTION {
Expand Down Expand Up @@ -235,14 +234,14 @@ func buildDatadogMetricTagConfigurationUpdate(d *schema.ResourceData, existingMe
attributes.SetIncludePercentiles(includePercentiles.(bool))
}

excludeTagsMode := d.Get("exclude_tags_mode")

if excludeTagsMode.(bool) && len(stringTags) == 0 {
return nil, fmt.Errorf("cannot use exclude_tags_mode without configuring any tags")
if excludeTagsMode, ok := d.GetOkExists("exclude_tags_mode"); ok {
excludeTagsModeVal := excludeTagsMode.(bool)
if excludeTagsModeVal && len(stringTags) == 0 {
return nil, fmt.Errorf("cannot use exclude_tags_mode without configuring any tags")
}
attributes.SetExcludeTagsMode(excludeTagsModeVal)
}

attributes.SetExcludeTagsMode(excludeTagsMode.(bool))

aggregationsArray, aggregationsFieldSet := d.GetOk("aggregations")
if aggregationsFieldSet {
if *existingMetricType == datadogV2.METRICTAGCONFIGURATIONMETRICTYPES_DISTRIBUTION {
Expand Down Expand Up @@ -317,9 +316,16 @@ func updateMetricTagConfigurationState(d *schema.ResourceData, metricTagConfigur
return diag.FromErr(err)
}

excludeTagsMode := attributes.GetExcludeTagsMode()
if err := d.Set("exclude_tags_mode", excludeTagsMode); err != nil {
return diag.FromErr(err)
// Only set exclude_tags_mode if it's explicitly present in the API response
if excludeTagsMode, ok := attributes.GetExcludeTagsModeOk(); ok {
if err := d.Set("exclude_tags_mode", *excludeTagsMode); err != nil {
return diag.FromErr(err)
}
} else {
// If the field is not present in the API response, clear it from state
if err := d.Set("exclude_tags_mode", nil); err != nil {
return diag.FromErr(err)
}
}
}

Expand All @@ -346,10 +352,7 @@ func resourceDatadogMetricTagConfigurationRead(ctx context.Context, d *schema.Re
d.SetId("")
return nil
}
if err != nil {
return utils.TranslateClientErrorDiag(err, httpresp, "metric tag configuration not found")
}
return diag.Errorf("error fetching metric tag configuration by name")
return utils.TranslateClientErrorDiag(err, httpresp, "metric tag configuration not found")
}
if httpresp.StatusCode != 200 {
return diag.Errorf("error fetching metric tag configuration by name, unexpected status code %d", httpresp.StatusCode)
Expand All @@ -375,7 +378,7 @@ func resourceDatadogMetricTagConfigurationUpdate(ctx context.Context, d *schema.
if httpresp == nil {
return diag.Errorf("error determining if tag configuration for metric exists")
}
if httpresp != nil && httpresp.StatusCode == 404 {
if httpresp.StatusCode == 404 {
return diag.Errorf("error updating tag configuration for metric, tag configuration does not exist")
}
if err := utils.CheckForUnparsed(metricTagConfigurationResponse); err != nil {
Expand Down
123 changes: 123 additions & 0 deletions datadog/tests/resource_datadog_metric_tag_configuration_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,129 @@ func testAccCheckDatadogMetricTagConfigurationExcludeTagsModeError(uniq string)
`, uniq)
}

func TestAccDatadogMetricTagConfiguration_ExcludeTagsMode(t *testing.T) {
t.Parallel()
ctx, accProviders := testAccProviders(context.Background(), t)
uniqueMetricTagConfig := strings.ReplaceAll(uniqueEntityName(ctx, t), "-", "_")
accProvider := testAccProvider(t, accProviders)

resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
ProviderFactories: accProviders,
CheckDestroy: testAccCheckDatadogMetricTagConfigurationDestroy(accProvider),
Steps: []resource.TestStep{
{
Config: testAccCheckDatadogMetricTagConfigurationExcludeTagsModeUnset(uniqueMetricTagConfig),
Check: resource.ComposeTestCheckFunc(
testAccCheckDatadogMetricTagConfigurationExists(accProvider),
resource.TestCheckResourceAttr(
"datadog_metric_tag_configuration.testing_unset", "metric_name", uniqueMetricTagConfig),
resource.TestCheckResourceAttr(
"datadog_metric_tag_configuration.testing_unset", "metric_type", "gauge"),
resource.TestCheckResourceAttr(
"datadog_metric_tag_configuration.testing_unset", "tags.#", "2"),
// When exclude_tags_mode is unset, it should not be present in state
resource.TestCheckNoResourceAttr(
"datadog_metric_tag_configuration.testing_unset", "exclude_tags_mode"),
),
},
{
Config: testAccCheckDatadogMetricTagConfigurationExcludeTagsModeTrue(uniqueMetricTagConfig),
Check: resource.ComposeTestCheckFunc(
testAccCheckDatadogMetricTagConfigurationExists(accProvider),
resource.TestCheckResourceAttr(
"datadog_metric_tag_configuration.testing_true", "metric_name", uniqueMetricTagConfig),
resource.TestCheckResourceAttr(
"datadog_metric_tag_configuration.testing_true", "exclude_tags_mode", "true"),
),
},
{
Config: testAccCheckDatadogMetricTagConfigurationExcludeTagsModeFalse(uniqueMetricTagConfig),
Check: resource.ComposeTestCheckFunc(
testAccCheckDatadogMetricTagConfigurationExists(accProvider),
resource.TestCheckResourceAttr(
"datadog_metric_tag_configuration.testing_false", "metric_name", uniqueMetricTagConfig),
resource.TestCheckResourceAttr(
"datadog_metric_tag_configuration.testing_false", "exclude_tags_mode", "false"),
),
},
{
// Test updating from false back to unset
Config: testAccCheckDatadogMetricTagConfigurationExcludeTagsModeUnset(uniqueMetricTagConfig),
Check: resource.ComposeTestCheckFunc(
testAccCheckDatadogMetricTagConfigurationExists(accProvider),
resource.TestCheckResourceAttr(
"datadog_metric_tag_configuration.testing_unset", "metric_name", uniqueMetricTagConfig),
resource.TestCheckNoResourceAttr(
"datadog_metric_tag_configuration.testing_unset", "exclude_tags_mode"),
),
},
},
})
}

func testAccCheckDatadogMetricTagConfigurationExcludeTagsModeUnset(uniq string) string {
return fmt.Sprintf(`
resource "datadog_metric_tag_configuration" "testing_unset" {
metric_name = "%s"
metric_type = "gauge"
tags = ["env", "service"]
# exclude_tags_mode is not set - allows all tags
}
`, uniq)
}

func testAccCheckDatadogMetricTagConfigurationExcludeTagsModeTrue(uniq string) string {
return fmt.Sprintf(`
resource "datadog_metric_tag_configuration" "testing_true" {
metric_name = "%s"
metric_type = "gauge"
tags = ["env", "service"]
exclude_tags_mode = true
}
`, uniq)
}

func testAccCheckDatadogMetricTagConfigurationExcludeTagsModeFalse(uniq string) string {
return fmt.Sprintf(`
resource "datadog_metric_tag_configuration" "testing_false" {
metric_name = "%s"
metric_type = "gauge"
tags = ["env", "service"]
exclude_tags_mode = false
}
`, uniq)
}

func testAccCheckDatadogMetricTagConfigurationExists(accProvider func() (*schema.Provider, error)) resource.TestCheckFunc {
return func(s *terraform.State) error {
provider, _ := accProvider()
meta := provider.Meta()
providerConf := meta.(*datadog.ProviderConfiguration)
apiInstances := providerConf.DatadogApiInstances
auth := providerConf.Auth

for _, r := range s.RootModule().Resources {
if r.Type != "datadog_metric_tag_configuration" {
continue
}

id := r.Primary.ID
_, resp, err := apiInstances.GetMetricsApiV2().ListTagConfigurationByName(auth, id)

if err != nil {
return fmt.Errorf("received an error retrieving metric_tag_configuration: %s", err.Error())
}

if resp.StatusCode != 200 {
return fmt.Errorf("metric_tag_configuration %s does not exist", id)
}
}

return nil
}
}

func testAccCheckDatadogMetricTagConfigurationDestroy(accProvider func() (*schema.Provider, error)) func(*terraform.State) error {
return func(s *terraform.State) error {
provider, _ := accProvider()
Expand Down
Loading