Skip to content

fix(dashboard): preserve unknown panel types on read/write round-trip#2856

Merged
tobio merged 12 commits intomainfrom
unknown-panel-preservation
May 11, 2026
Merged

fix(dashboard): preserve unknown panel types on read/write round-trip#2856
tobio merged 12 commits intomainfrom
unknown-panel-preservation

Conversation

@tobio
Copy link
Copy Markdown
Member

@tobio tobio commented May 11, 2026

Summary

Fixes a bug where the dashboard resource's read path silently stripped the id, grid, and config of any panel type it did not recognize (e.g., discover_session, image, slo_alerts). Refreshing or importing a dashboard containing such panels corrupted state invisibly.

Changes

  • Read path (mapPanelFromAPI): replace the destructive default branch with logic that preserves id, grid, type, and the full raw API config JSON in config_json for unrecognized panel types.
  • Write path: when no typed block matches and a preserved raw payload exists in config_json, re-marshal that payload into the API request unchanged. When no typed block matches and no preserved payload exists, return the existing unsupported-type error.
  • Unit tests: unknown-type panel read produces preserved fields; second write replays the payload; validation rejects user-authored unknown types without a payload.
  • Acceptance test (TestAccResourceDashboardUnknownPanel): creates a dashboard via the Kibana API with an unrecognized panel type, imports it into Terraform, and verifies a no-op plan.

Changelog

Customer impact: fix
Summary: Preserve unknown Kibana dashboard panel types during Terraform read/write round-trips.

Spec

OpenSpec change: fix-dashboard-unknown-panel-preservation

Extends REQ-010 (panels and config_json round-trip) to cover unknown panel types. The raw preserved payload is stored in the existing config_json attribute (already Optional: true, Computed: true), which means it is visible via terraform show but not user-authorable for unknown types without an existing preserved payload.

Testing

  • Unit tests: go test ./internal/kibana/dashboard/...
  • Acceptance test: TestAccResourceDashboardUnknownPanel ✅ (7.3s vs live ES 9.4.0 + Kibana)
  • Build: make build

tobio added 6 commits May 11, 2026 15:12
…path)

Replace the  branch in  that was silently
stripping panel identity for unrecognized panel types (e.g.
, , ). The new logic:

1. Marshals the raw  JSON and extracts uid=501(tobio) gid=20(staff) groups=20(staff),12(everyone),61(localaccounts),79(_appserverusr),80(admin),81(_appserveradm),701(com.apple.sharepoint.group.1),33(_appstore),98(_lpadmin),100(_lpoperator),204(_developer),250(_analyticsusers),395(com.apple.access_ftp),398(com.apple.access_screensharing),399(com.apple.access_ssh),400(com.apple.access_remote_ae), , and
    to preserve them in the Terraform state.
2. Stores the raw API config in , which flows through the
   existing semantic-defaults machinery ().
3. Clears all typed config blocks to avoid stale data from prior state.

On the write path (), unknown panel types with  set
are now reconstructed by building the full panel JSON (type + grid +
id + config) and setting it directly on the  union
via .

Also adds a  helper to convert float64 from JSON decoding
into *float32 for .

Removes the test case that expected an error for type  with
, since this is now handled as a round-tripped unknown
panel type.
- Fix float32Ptr to not discard zero grid values (w=0, h=0 are valid)
- Improve toAPI catch-all error to distinguish known vs unknown panel types:
  unknown types now get a clear 'not yet supported' message
- Add read-path test for unknown panel type in Test_mapPanelsFromAPI
- Add write-path test for unknown panel type in Test_panelsToAPI
- Add Test_unknownPanelRoundTrip verifying round-trip preservation
- Add Test_unknownPanelToAPIErrorWithoutConfigJSON for user-authored error
Create a new acceptance test TestAccResourceDashboardUnknownPanel that:
1. Creates a dashboard via the Kibana REST API with a 'discover_session' panel
   (an unknown panel type that has no typed config block in the provider)
2. Imports the dashboard into Terraform state
3. Verifies the import preserves: panel id, grid (x, y, w, h), type, and config_json
4. Runs a second step with ConfigPlanChecks to verify no-op (empty plan)

The test uses a PreConfig function to create the dashboard externally since
unknown panel types cannot be authored in Terraform configuration.
ImportStateIdFunc is used to dynamically set the import ID from the
PreConfig-created dashboard.
Copilot AI review requested due to automatic review settings May 11, 2026 06:58
@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented May 11, 2026

PR Changelog Check passedno-changelog label is set.

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR aims to prevent state corruption in elasticstack_kibana_dashboard when Kibana dashboards contain panel types the provider doesn’t currently have typed config blocks for, by preserving and round-tripping those panels’ raw config via config_json.

Changes:

  • Preserve unknown panel id, grid, type, and raw config into config_json on read, and clear any typed config blocks.
  • On write, if a panel has no typed config block but has preserved config_json, reconstruct the panel JSON and emit it back to the API.
  • Add unit tests for unknown panel preservation/round-trip and add an acceptance test intended to validate unknown panel handling.

OpenSpec requirements analysis (delta spec)

  • Internal consistency: Inconsistent — REQ-010 still states panel-level config_json is supported only for markdown/vis, while the updated unknown-panel clause introduces using config_json for unknown types on write (needs wording clarification to distinguish practitioner-authored vs computed/preserved usage).
  • Implementation compliance: Partially met — the core preservation approach is implemented, but the unknown-panel grid handling can incorrectly force omitted w/h to 0 (potentially generating invalid API payloads), and the spec’s “validate/plan” rejection of authored unknown types does not appear to be enforced until apply-time.
  • Test opportunities: The acceptance test as written does not currently exercise the PR description’s “API-created unknown panel -> import -> no-op plan” flow.

Reviewed changes

Copilot reviewed 8 out of 8 changed files in this pull request and generated 7 comments.

Show a summary per file
File Description
openspec/changes/fix-dashboard-unknown-panel-preservation/tasks.md Marks tasks complete; checklist wording appears out of sync with the chosen config_json approach.
openspec/changes/fix-dashboard-unknown-panel-preservation/specs/kibana-dashboard/spec.md Updates REQ-010 to require unknown panel preservation via config_json.
openspec/changes/fix-dashboard-unknown-panel-preservation/design.md Updates design decision to reuse config_json for unknown panel payload storage.
internal/kibana/dashboard/testdata/TestAccResourceDashboardUnknownPanel/import/main.tf Adds import-oriented test config for unknown-panel scenarios.
internal/kibana/dashboard/testdata/TestAccResourceDashboardUnknownPanel/create/main.tf Adds create config used by the new acceptance test.
internal/kibana/dashboard/models_panels.go Implements unknown panel read preservation and write reconstruction logic.
internal/kibana/dashboard/models_panels_test.go Adds unit tests for unknown panel preservation and round-trip behavior.
internal/kibana/dashboard/acc_unknown_panels_test.go Adds an acceptance test around unknown panel handling via out-of-band API mutation.

Comment thread internal/kibana/dashboard/models_panels.go Outdated
Comment thread internal/kibana/dashboard/models_panels.go
Comment thread internal/kibana/dashboard/acc_unknown_panels_test.go
Comment thread internal/kibana/dashboard/acc_unknown_panels_test.go Outdated
Comment thread openspec/changes/fix-dashboard-unknown-panel-preservation/tasks.md Outdated
tobio added 3 commits May 11, 2026 17:21
…ervation

- Add presence checks for grid.w/h (avoid treating missing=0)
- Clear id/grid/config_json before populating from API to prevent stale
  state carry-over in the unknown-panel default branch
- Replace manual for-loop with slices.Contains (modernize lint fix)
- Wrap long error message string to satisfy lll lint rule
- Use clients.CompositeIDFromStr helper in acceptance test
- Fix testifylint: require.Empty instead of require.Len(t, x, 0)
- Clarify acceptance test comment: plan is non-empty (config vs state
  diverge), not a no-op, which is the expected and correct behaviour
…rved unknown panels

- Distinguish practitioner-authored config_json from provider-populated
  config_json (set during read for unknown panel type preservation)
- Clarify write-path exception: preserved payloads re-emitted without error
- Update tasks.md task 1.1 to reflect actual implementation (config_json
  reuse instead of rawConfig private field)
@github-actions
Copy link
Copy Markdown
Contributor

Commit pushed: 9406099

Generated by OpenSpec verify (label)

Copy link
Copy Markdown
Contributor

@github-actions github-actions Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Verification Report: fix-dashboard-unknown-panel-preservation

Summary

Dimension Status
Completeness 9/10 tasks done (task 4.2 is archive — handled below); 6/6 spec requirements covered
Correctness All requirements implemented and tested; scenarios match spec
Coherence Implementation follows design decisions; code patterns consistent

CI Status

All checks passing: Build, Lint, CodeQL, OpenSpec Gate, Provider Gate, Check PR changelog, and all 40+ Matrix Acceptance Tests (8.0.1 through 9.4.0).

Issues by Priority

CRITICAL: None

WARNING: None

SUGGESTION:

  1. internal/kibana/dashboard/testdata/TestAccResourceDashboardUnknownPanel/import/main.tf — unused test fixture (both test steps use "create" directory). Minor cleanup opportunity.

Out-of-scope / unassociated changes

All non-change-artifact files are relevant to the change:

  • internal/kibana/dashboard/models_panels.go — read/write path implementation (tasks 1.x, 2.x)
  • internal/kibana/dashboard/models_panels_test.go — unit tests (task 3.1)
  • internal/kibana/dashboard/acc_unknown_panels_test.go — acceptance test (task 3.2)
  • internal/kibana/dashboard/testdata/TestAccResourceDashboardUnknownPanel/create/main.tf — acceptance test fixture
  • internal/kibana/dashboard/testdata/TestAccResourceDashboardUnknownPanel/import/main.tf — test fixture (unused, but related to the change scope)

No unassociated files.

Final Assessment

All checks passed. Zero CRITICAL issues, zero unassociated files. Ready for archive.

Generated by OpenSpec verify (label) for issue #2856 · ● 949.7K

@@ -0,0 +1,20 @@
variable "dashboard_title" {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

SUGGESTION: This test fixture is not referenced by any test step — both steps in TestAccResourceDashboardUnknownPanel use acctest.NamedTestCaseDirectory("create"). Consider removing this file or adding a step that uses the import directory.

@tobio tobio enabled auto-merge (squash) May 11, 2026 09:45
@tobio tobio merged commit 77975d2 into main May 11, 2026
72 checks passed
@tobio tobio deleted the unknown-panel-preservation branch May 11, 2026 10:07
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants