diff --git a/pkg/models/dashboards.go b/pkg/models/dashboards.go index 733d989b278..242b6d512d3 100644 --- a/pkg/models/dashboards.go +++ b/pkg/models/dashboards.go @@ -96,6 +96,7 @@ func (cmd *SaveDashboardCommand) GetDashboardModel() *Dashboard { dash.UpdatedBy = cmd.UserId dash.OrgId = cmd.OrgId + dash.PluginId = cmd.PluginId dash.UpdateSlug() return dash } @@ -120,6 +121,7 @@ type SaveDashboardCommand struct { UserId int64 `json:"userId"` OrgId int64 `json:"-"` Overwrite bool `json:"overwrite"` + PluginId string `json:"-"` Result *Dashboard } diff --git a/pkg/models/plugin_settings.go b/pkg/models/plugin_settings.go index dbeaf441156..21c48411797 100644 --- a/pkg/models/plugin_settings.go +++ b/pkg/models/plugin_settings.go @@ -86,3 +86,9 @@ type GetPluginSettingByIdQuery struct { OrgId int64 Result *PluginSetting } + +type PluginStateChangedEvent struct { + PluginId string + OrgId int64 + Enabled bool +} diff --git a/pkg/plugins/dashboard_importer.go b/pkg/plugins/dashboard_importer.go index 8f6998d344d..1b3e4bac182 100644 --- a/pkg/plugins/dashboard_importer.go +++ b/pkg/plugins/dashboard_importer.go @@ -68,6 +68,7 @@ func ImportDashboard(cmd *ImportDashboardCommand) error { OrgId: cmd.OrgId, UserId: cmd.UserId, Overwrite: cmd.Overwrite, + PluginId: cmd.PluginId, } if err := bus.Dispatch(&saveCmd); err != nil { diff --git a/pkg/plugins/dashboards.go b/pkg/plugins/dashboards.go index 8bde60b64c8..c4b3915106d 100644 --- a/pkg/plugins/dashboards.go +++ b/pkg/plugins/dashboards.go @@ -18,7 +18,7 @@ type PluginDashboardInfoDTO struct { Revision int64 `json:"revision"` Description string `json:"description"` Path string `json:"path"` - Removed bool + Removed bool `json:"removed"` } func GetPluginDashboards(orgId int64, pluginId string) ([]*PluginDashboardInfoDTO, error) { diff --git a/pkg/plugins/dashboards_updater.go b/pkg/plugins/dashboards_updater.go index 3a0714eb675..09f3e70a9a9 100644 --- a/pkg/plugins/dashboards_updater.go +++ b/pkg/plugins/dashboards_updater.go @@ -7,6 +7,10 @@ import ( m "github.com/grafana/grafana/pkg/models" ) +func init() { + bus.AddEventListener(handlePluginStateChanged) +} + func updateAppDashboards() { time.Sleep(time.Second * 1) @@ -20,9 +24,14 @@ func updateAppDashboards() { } for _, pluginSetting := range query.Result { - if appDef, exist := Apps[pluginSetting.PluginId]; exist { - if appDef.Info.Version != pluginSetting.PluginVersion { - handleAppPluginUpdated(appDef, pluginSetting.OrgId) + // ignore disabled plugins + if !pluginSetting.Enabled { + continue + } + + if pluginDef, exist := Plugins[pluginSetting.PluginId]; exist { + if pluginDef.Info.Version != pluginSetting.PluginVersion { + syncPluginDashboards(pluginDef, pluginSetting.OrgId) } } } @@ -49,11 +58,11 @@ func autoUpdateAppDashboard(pluginDashInfo *PluginDashboardInfoDTO, orgId int64) return nil } -func handleAppPluginUpdated(appDef *AppPlugin, orgId int64) { - plog.Info("App update detected", "pluginId", appDef.Id) +func syncPluginDashboards(pluginDef *PluginBase, orgId int64) { + plog.Info("Syncing plugin dashboards to DB", "pluginId", pluginDef.Id) // Get plugin dashboards - if dashboards, err := GetPluginDashboards(orgId, appDef.Id); err != nil { + if dashboards, err := GetPluginDashboards(orgId, pluginDef.Id); err != nil { plog.Error("Failed to load app dashboards", "error", err) return } else { @@ -61,7 +70,7 @@ func handleAppPluginUpdated(appDef *AppPlugin, orgId int64) { for _, dash := range dashboards { if dash.ImportedRevision != dash.Revision { if err := autoUpdateAppDashboard(dash, orgId); err != nil { - plog.Error("Failed to auto update app dashboard", "pluginId", appDef.Id, "error", err) + plog.Error("Failed to auto update app dashboard", "pluginId", pluginDef.Id, "error", err) return } } @@ -69,7 +78,7 @@ func handleAppPluginUpdated(appDef *AppPlugin, orgId int64) { } // update version in plugin_setting table to mark that we have processed the update - query := m.GetPluginSettingByIdQuery{PluginId: appDef.Id, OrgId: orgId} + query := m.GetPluginSettingByIdQuery{PluginId: pluginDef.Id, OrgId: orgId} if err := bus.Dispatch(&query); err != nil { plog.Error("Failed to read plugin setting by id", "error", err) return @@ -79,10 +88,36 @@ func handleAppPluginUpdated(appDef *AppPlugin, orgId int64) { cmd := m.UpdatePluginSettingVersionCmd{ OrgId: appSetting.OrgId, PluginId: appSetting.PluginId, - PluginVersion: appDef.Info.Version, + PluginVersion: pluginDef.Info.Version, } if err := bus.Dispatch(&cmd); err != nil { plog.Error("Failed to update plugin setting version", "error", err) } } + +func handlePluginStateChanged(event *m.PluginStateChangedEvent) error { + plog.Info("Plugin state changed", "pluginId", event.PluginId, "enabled", event.Enabled) + + if event.Enabled { + syncPluginDashboards(Plugins[event.PluginId], event.OrgId) + } else { + query := m.GetDashboardsByPluginIdQuery{PluginId: event.PluginId, OrgId: event.OrgId} + + if err := bus.Dispatch(&query); err != nil { + return err + } else { + for _, dash := range query.Result { + deleteCmd := m.DeleteDashboardCommand{OrgId: dash.OrgId, Slug: dash.Slug} + + plog.Info("Deleting plugin dashboard", "pluginId", event.PluginId, "dashboard", dash.Slug) + + if err := bus.Dispatch(&deleteCmd); err != nil { + return err + } + } + } + } + + return nil +} diff --git a/pkg/services/sqlstore/plugin_setting.go b/pkg/services/sqlstore/plugin_setting.go index f3fcc2a9c1d..8121b8c7b4b 100644 --- a/pkg/services/sqlstore/plugin_setting.go +++ b/pkg/services/sqlstore/plugin_setting.go @@ -62,17 +62,36 @@ func UpdatePluginSetting(cmd *m.UpdatePluginSettingCmd) error { Created: time.Now(), Updated: time.Now(), } + + // add state change event on commit success + sess.events = append(sess.events, &m.PluginStateChangedEvent{ + PluginId: cmd.PluginId, + OrgId: cmd.OrgId, + Enabled: cmd.Enabled, + }) + _, err = sess.Insert(&pluginSetting) return err } else { for key, data := range cmd.SecureJsonData { pluginSetting.SecureJsonData[key] = util.Encrypt([]byte(data), setting.SecretKey) } + + // add state change event on commit success + if pluginSetting.Enabled != cmd.Enabled { + sess.events = append(sess.events, &m.PluginStateChangedEvent{ + PluginId: cmd.PluginId, + OrgId: cmd.OrgId, + Enabled: cmd.Enabled, + }) + } + pluginSetting.Updated = time.Now() pluginSetting.Enabled = cmd.Enabled pluginSetting.JsonData = cmd.JsonData pluginSetting.Pinned = cmd.Pinned pluginSetting.PluginVersion = cmd.PluginVersion + _, err = sess.Id(pluginSetting.Id).Update(&pluginSetting) return err } diff --git a/public/app/features/plugins/import_list/import_list.html b/public/app/features/plugins/import_list/import_list.html index b984a9d8be5..715f5b3be74 100644 --- a/public/app/features/plugins/import_list/import_list.html +++ b/public/app/features/plugins/import_list/import_list.html @@ -19,14 +19,14 @@