From 566eff7d4b2340fa62f447160ccb9d09fa8c8c9e Mon Sep 17 00:00:00 2001 From: Maria Bazhlekova Date: Fri, 4 Mar 2022 17:15:48 -0600 Subject: [PATCH] fix: handle filter_current_dashboard on update --- newrelic/resource_newrelic_one_dashboard.go | 11 ++++ .../resource_newrelic_one_dashboard_test.go | 62 ++++++++++++++++++- newrelic/structures_newrelic_one_dashboard.go | 17 +++-- 3 files changed, 81 insertions(+), 9 deletions(-) diff --git a/newrelic/resource_newrelic_one_dashboard.go b/newrelic/resource_newrelic_one_dashboard.go index 86830ba22..18ad889f6 100644 --- a/newrelic/resource_newrelic_one_dashboard.go +++ b/newrelic/resource_newrelic_one_dashboard.go @@ -501,6 +501,17 @@ func resourceNewRelicOneDashboardUpdate(ctx context.Context, d *schema.ResourceD defaultInfo := map[string]interface{}{ "account_id": accountID, } + + filterWidgets, err := findDashboardWidgetFilterCurrentDashboard(d) + if err != nil { + return diag.FromErr(err) + } + + err = setDashboardWidgetFilterCurrentDashboardLinkedEntity(d, filterWidgets) + if err != nil { + return diag.FromErr(err) + } + dashboard, err := expandDashboardInput(d, defaultInfo) if err != nil { return diag.FromErr(err) diff --git a/newrelic/resource_newrelic_one_dashboard_test.go b/newrelic/resource_newrelic_one_dashboard_test.go index 4c3c54d4f..ac4becf69 100644 --- a/newrelic/resource_newrelic_one_dashboard_test.go +++ b/newrelic/resource_newrelic_one_dashboard_test.go @@ -170,7 +170,7 @@ func TestAccNewRelicOneDashboard_FilterCurrentDashboard(t *testing.T) { CheckDestroy: testAccCheckNewRelicOneDashboardDestroy, Steps: []resource.TestStep{ { - Config: testAccCheckNewRelicOneDashboardConfig_FilterCurrentDashboard(rName, strconv.Itoa(testAccountID)), + Config: testAccCheckNewRelicOneDashboardConfig_FilterCurrentDashboard(rName, strconv.Itoa(testAccountID), "true"), Check: resource.ComposeTestCheckFunc( testAccCheckNewRelicOneDashboard_FilterCurrentDashboard("newrelic_one_dashboard.bar", 5), ), @@ -179,6 +179,30 @@ func TestAccNewRelicOneDashboard_FilterCurrentDashboard(t *testing.T) { }) } +func TestAccNewRelicOneDashboard_UnlinkFilterCurrentDashboard(t *testing.T) { + rName := fmt.Sprintf("tf-test-%s", acctest.RandString(5)) + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckNewRelicOneDashboardDestroy, + Steps: []resource.TestStep{ + { + Config: testAccCheckNewRelicOneDashboardConfig_FilterCurrentDashboard(rName, strconv.Itoa(testAccountID), "true"), + Check: resource.ComposeTestCheckFunc( + testAccCheckNewRelicOneDashboard_FilterCurrentDashboard("newrelic_one_dashboard.bar", 5), + ), + }, + { + Config: testAccCheckNewRelicOneDashboardConfig_FilterCurrentDashboard(rName, strconv.Itoa(testAccountID), "false"), + Check: resource.ComposeTestCheckFunc( + testAccCheckNewRelicOneDashboard_UnlinkFilterCurrentDashboard("newrelic_one_dashboard.bar"), + ), + }, + }, + }) +} + // testAccCheckNewRelicOneDashboard_FilterCurrentDashboard fetches the dashboard resource after creation, with an optional sleep time // used when we know the async nature of the API will mess with consistent testing. The filter_current_dashboard requires a second call to update // the linked_entity_guid to add the page GUID. This also checks to make sure the page GUID matches what has been added. @@ -221,6 +245,38 @@ func testAccCheckNewRelicOneDashboard_FilterCurrentDashboard(name string, sleepS } } +// testAccCheckNewRelicOneDashboard_FilterCurrentDashboard fetches the dashboard resource after creation, with an optional sleep time +// used when we know the async nature of the API will mess with consistent testing. The filter_current_dashboard requires a second call to update +// the linked_entity_guid to add the page GUID. This also checks to make sure the page GUID matches what has been added. +func testAccCheckNewRelicOneDashboard_UnlinkFilterCurrentDashboard(name string) resource.TestCheckFunc { + return func(s *terraform.State) error { + rs, ok := s.RootModule().Resources[name] + if !ok { + return fmt.Errorf("not found: %s", name) + } + if rs.Primary.ID == "" { + return fmt.Errorf("no dashboard ID is set") + } + + client := testAccProvider.Meta().(*ProviderConfig).NewClient + + found, err := client.Dashboards.GetDashboardEntity(common.EntityGUID(rs.Primary.ID)) + if err != nil { + return err + } + + if string(found.GUID) != rs.Primary.ID { + return fmt.Errorf("dashboard not found: %v - %v", rs.Primary.ID, found) + } + + if found.Pages[0].Widgets[0].LinkedEntities != nil { + return fmt.Errorf("Entities still linked") + } + + return nil + } +} + // testAccCheckNewRelicOneDashboardConfig_TwoPageBasic generates a TF config snippet for a simple // two page dashboard. func testAccCheckNewRelicOneDashboardConfig_TwoPageBasic(dashboardName string, accountID string) string { @@ -264,7 +320,7 @@ func testAccCheckNewRelicOneDashboardConfig_PageSimple(pageName string) string { ` } -func testAccCheckNewRelicOneDashboardConfig_FilterCurrentDashboard(dashboardName string, accountID string) string { +func testAccCheckNewRelicOneDashboardConfig_FilterCurrentDashboard(dashboardName string, accountID string, filterDashboard string) string { return ` resource "newrelic_one_dashboard" "bar" { @@ -284,7 +340,7 @@ func testAccCheckNewRelicOneDashboardConfig_FilterCurrentDashboard(dashboardName } # Linking to self - filter_current_dashboard = true + filter_current_dashboard = ` + filterDashboard + ` } } } diff --git a/newrelic/structures_newrelic_one_dashboard.go b/newrelic/structures_newrelic_one_dashboard.go index a63436691..89330be6f 100644 --- a/newrelic/structures_newrelic_one_dashboard.go +++ b/newrelic/structures_newrelic_one_dashboard.go @@ -3,7 +3,6 @@ package newrelic import ( "encoding/json" "fmt" - "log" "strings" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" @@ -892,11 +891,10 @@ func findDashboardWidgetFilterCurrentDashboard(d *schema.ResourceData) ([]interf // Function to set the page guid as the linked entity now that the page is created func setDashboardWidgetFilterCurrentDashboardLinkedEntity(d *schema.ResourceData, filterWidgets []interface{}) error { - - if len(filterWidgets) < 1 { - log.Printf("[INFO] Empty list of widgets to filter") - return nil - } + //if len(filterWidgets) < 1 { + // log.Printf("[INFO] Empty list of widgets to filter") + // return nil + //} selfLinkingWidgets := []string{"widget_bar", "widget_pie", "widget_table"} @@ -907,6 +905,13 @@ func setDashboardWidgetFilterCurrentDashboardLinkedEntity(d *schema.ResourceData if widgets, ok := p[widgetType]; ok { for _, k := range widgets.([]interface{}) { w := k.(map[string]interface{}) + if l, ok := w["linked_entity_guids"]; ok && len(l.([]interface{})) == 1 { + for _, le := range l.([]interface{}) { + if f, ok := w["filter_current_dashboard"]; ok && f == false && le.(string) == p["guid"] { + w["linked_entity_guids"] = nil + } + } + } for _, f := range filterWidgets { e := f.(map[string]interface{}) if e["page"] == i {