Skip to content

Commit

Permalink
Merge pull request #962 from newrelic/fix/dashboard-cross-account-mess
Browse files Browse the repository at this point in the history
fix(dashboard): use state migration to fix 500 error when upgrading from v2.7.5 to v2.8+
  • Loading branch information
sanderblue authored Oct 15, 2020
2 parents 55b2269 + 160c3e6 commit 5a60973
Show file tree
Hide file tree
Showing 4 changed files with 195 additions and 220 deletions.
98 changes: 98 additions & 0 deletions newrelic/resource_newrelic_dashboard.go
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,104 @@ var (
)

func resourceNewRelicDashboard() *schema.Resource {
return &schema.Resource{
Create: resourceNewRelicDashboardCreate,
Read: resourceNewRelicDashboardRead,
Update: resourceNewRelicDashboardUpdate,
Delete: resourceNewRelicDashboardDelete,
Importer: &schema.ResourceImporter{
State: schema.ImportStatePassthrough,
},
Schema: map[string]*schema.Schema{
"title": {
Type: schema.TypeString,
Required: true,
Description: "The title of the dashboard.",
},
"icon": {
Type: schema.TypeString,
Optional: true,
Default: "bar-chart",
ValidateFunc: validation.StringInSlice(validIconValues, false),
Description: "The icon for the dashboard.",
},
"visibility": {
Type: schema.TypeString,
Optional: true,
Default: "all",
ValidateFunc: validation.StringInSlice([]string{"owner", "all"}, false),
Description: "Determines who can see the dashboard in an account. Valid values are all or owner. Defaults to all.",
},
"dashboard_url": {
Type: schema.TypeString,
Computed: true,
Description: "The URL for viewing the dashboard.",
},
"editable": {
Type: schema.TypeString,
Optional: true,
Default: "editable_by_all",
ValidateFunc: validation.StringInSlice([]string{"read_only", "editable_by_owner", "editable_by_all", "all"}, false),
Description: "Determines who can edit the dashboard in an account. Valid values are all, editable_by_all, editable_by_owner, or read_only. Defaults to editable_by_all.",
},
"grid_column_count": {
Type: schema.TypeInt,
Optional: true,
Default: 3,
ValidateFunc: validation.IntInSlice([]int{3, 12}),
Description: "New Relic One supports a 3 column grid or a 12 column grid. New Relic Insights supports a 3 column grid.",
},
"filter": {
Type: schema.TypeList,
Optional: true,
MaxItems: 1,
Description: "A nested block that describes a dashboard filter. Exactly one nested filter block is allowed.",
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"event_types": {
Type: schema.TypeSet,
Elem: &schema.Schema{Type: schema.TypeString},
Required: true,
Set: schema.HashString,
},
"attributes": {
Type: schema.TypeSet,
Elem: &schema.Schema{Type: schema.TypeString},
Optional: true,
Set: schema.HashString,
},
},
},
},
"widget": {
Type: schema.TypeSet,
Optional: true,
MaxItems: 300,
Description: "A nested block that describes a visualization. Up to 300 widget blocks are allowed in a dashboard definition.",
Elem: widgetSchemaElem(),
},
},
SchemaVersion: 1,
StateUpgraders: []schema.StateUpgrader{
{
Type: resourceV0().CoreConfigSchema().ImpliedType(),
Upgrade: migrateStateV0toV1,
Version: 0,
},
},
}
}

// v2.8.0 changed `widget` from TypeSet to TypeList, but we didn't
// use state migration. Since this change broke things for some
// folks trying to upgrade from v2.7.5 to v2.8.0, we have to switch
// back to TypeSet. So this time we need to make sure we migrate
// the state to the latest SchemaVersion, this basically reverts
// the previous change and hopefully allows those that upgraded to
// v2.8+ to continue to upgrade to which ever version this is
// released in. In the future, we should always use state migration
// if an attribute changes its schema type.
func resourceV0() *schema.Resource {
return &schema.Resource{
Create: resourceNewRelicDashboardCreate,
Read: resourceNewRelicDashboardRead,
Expand Down
11 changes: 3 additions & 8 deletions newrelic/resource_newrelic_dashboard_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -57,14 +57,9 @@ func TestAccNewRelicDashboard_CrossAccountWidget(t *testing.T) {
Steps: []resource.TestStep{
// Test: Create
{
Config: testAccCheckNewRelicDashboardConfigCrossAccountWidgets(rName, widgetPrimaryAcct, widgetSubAcct),
Check: resource.ComposeTestCheckFunc(
testAccCheckNewRelicDashboardExists("newrelic_dashboard.foo"),
),
},
// Test: Reodering widgets should NOT drift since we sort before storing in state.
{
Config: testAccCheckNewRelicDashboardConfigCrossAccountWidgets(rName, widgetSubAcct, widgetPrimaryAcct),
// cross-account widgets cause drift due to the API not returning that data
ExpectNonEmptyPlan: true,
Config: testAccCheckNewRelicDashboardConfigCrossAccountWidgets(rName, widgetPrimaryAcct, widgetSubAcct),
Check: resource.ComposeTestCheckFunc(
testAccCheckNewRelicDashboardExists("newrelic_dashboard.foo"),
),
Expand Down
Loading

0 comments on commit 5a60973

Please sign in to comment.