@@ -88,6 +88,28 @@ func (m folderDashboardPlanModifier) PlanModifyString(ctx context.Context, req p
8888 }
8989}
9090
91+ // configJSONPlanModifier normalizes config_json during planning so the plan value
92+ // matches the stored form (compact JSON, id/version/panel-ids removed). Without this,
93+ // the Plugin Framework's post-apply consistency check fails when the user provides
94+ // pretty-printed or un-normalized JSON.
95+ type configJSONPlanModifier struct {}
96+
97+ func (configJSONPlanModifier ) Description (_ context.Context ) string {
98+ return "Normalizes config_json to compact JSON with id and version removed."
99+ }
100+
101+ func (m configJSONPlanModifier ) MarkdownDescription (ctx context.Context ) string {
102+ return m .Description (ctx )
103+ }
104+
105+ func (configJSONPlanModifier ) PlanModifyString (_ context.Context , req planmodifier.StringRequest , resp * planmodifier.StringResponse ) {
106+ if req .ConfigValue .IsNull () || req .ConfigValue .IsUnknown () {
107+ return
108+ }
109+ normalized := NormalizeDashboardConfigJSON (req .ConfigValue .ValueString ())
110+ resp .PlanValue = types .StringValue (normalized )
111+ }
112+
91113// jsonStringValidator validates that a string is valid JSON.
92114type jsonStringValidator struct {}
93115
@@ -173,6 +195,7 @@ Manages Grafana dashboards.
173195 Required : true ,
174196 Description : "The complete dashboard model JSON." ,
175197 Validators : []validator.String {jsonStringValidator {}},
198+ PlanModifiers : []planmodifier.String {configJSONPlanModifier {}},
176199 },
177200 "overwrite" : frameworkSchema.BoolAttribute {
178201 Optional : true ,
0 commit comments