diff --git a/controllers/config/controller_config.go b/controllers/config/controller_config.go index de49222ee..4cc1590d1 100644 --- a/controllers/config/controller_config.go +++ b/controllers/config/controller_config.go @@ -40,7 +40,7 @@ type ControllerConfig struct { *sync.Mutex Values map[string]interface{} Plugins map[string]v1alpha1.PluginList - Dashboards []*v1alpha1.GrafanaDashboardRef + Dashboards map[string][]*v1alpha1.GrafanaDashboardRef } var instance *ControllerConfig @@ -52,7 +52,7 @@ func GetControllerConfig() *ControllerConfig { Mutex: &sync.Mutex{}, Values: map[string]interface{}{}, Plugins: map[string]v1alpha1.PluginList{}, - Dashboards: []*v1alpha1.GrafanaDashboardRef{}, + Dashboards: map[string][]*v1alpha1.GrafanaDashboardRef{}, } }) return instance @@ -86,17 +86,17 @@ func (c *ControllerConfig) SetPluginsFor(dashboard *v1alpha1.GrafanaDashboard) { c.Plugins[id] = dashboard.Spec.Plugins } -func (c *ControllerConfig) RemovePluginsFor(namespace, name string) { - id := c.GetDashboardId(namespace, name) +func (c *ControllerConfig) RemovePluginsFor(dashboard *v1alpha1.GrafanaDashboardRef) { + id := c.GetDashboardId(dashboard.Namespace, dashboard.Name) delete(c.Plugins, id) } func (c *ControllerConfig) AddDashboard(dashboard *v1alpha1.GrafanaDashboard, folderId *int64, folderName string) { ns := dashboard.Namespace - if i, exists := c.HasDashboard(dashboard.UID()); !exists { + if i, exists := c.HasDashboard(ns, dashboard.UID()); !exists { c.Lock() defer c.Unlock() - c.Dashboards = append(c.Dashboards, &v1alpha1.GrafanaDashboardRef{ + c.Dashboards[ns] = append(c.Dashboards[ns], &v1alpha1.GrafanaDashboardRef{ Name: dashboard.Name, Namespace: ns, UID: dashboard.UID(), @@ -107,7 +107,7 @@ func (c *ControllerConfig) AddDashboard(dashboard *v1alpha1.GrafanaDashboard, fo } else { c.Lock() defer c.Unlock() - c.Dashboards[i] = &v1alpha1.GrafanaDashboardRef{ + c.Dashboards[ns][i] = &v1alpha1.GrafanaDashboardRef{ Name: dashboard.Name, Namespace: ns, UID: dashboard.UID(), @@ -118,9 +118,9 @@ func (c *ControllerConfig) AddDashboard(dashboard *v1alpha1.GrafanaDashboard, fo } } -func (c *ControllerConfig) HasDashboard(str string) (int, bool) { - for i, v := range c.Dashboards { - if v.UID == str { +func (c *ControllerConfig) HasDashboard(ns, uid string) (int, bool) { + for i, v := range c.Dashboards[ns] { + if v.UID == uid { return i, true } } @@ -130,45 +130,49 @@ func (c *ControllerConfig) HasDashboard(str string) (int, bool) { func (c *ControllerConfig) InvalidateDashboards() { c.Lock() defer c.Unlock() - for _, v := range c.Dashboards { - v.Hash = "" + for _, ds := range c.Dashboards { + for _, v := range ds { + v.Hash = "" + } } } -func (c *ControllerConfig) SetDashboards(dashboards []*v1alpha1.GrafanaDashboardRef) { - c.Lock() - defer c.Unlock() - c.Dashboards = dashboards -} - func (c *ControllerConfig) RemoveDashboard(hash string) { - if i, exists := c.HasDashboard(hash); exists { - c.Lock() - defer c.Unlock() - list := c.Dashboards - list[i] = list[len(list)-1] - list = list[:len(list)-1] - c.Dashboards = list + for ns := range c.Dashboards { + if i, exists := c.HasDashboard(ns, hash); exists { + c.Lock() + defer c.Unlock() + list := c.Dashboards[ns] + list[i] = list[len(list)-1] + list = list[:len(list)-1] + c.Dashboards[ns] = list + } } } func (c *ControllerConfig) GetDashboards(namespace string) []*v1alpha1.GrafanaDashboardRef { c.Lock() defer c.Unlock() - // Checking for dashboards at the cluster level? across namespaces? - if namespace == "" { - var dashboards []*v1alpha1.GrafanaDashboardRef - dashboards = append(dashboards, c.Dashboards...) - return dashboards + if c.Dashboards[namespace] != nil { + return c.Dashboards[namespace] } - if c.Dashboards != nil { - return c.Dashboards - } return []*v1alpha1.GrafanaDashboardRef{} } +func (c *ControllerConfig) GetAllDashboards() []*v1alpha1.GrafanaDashboardRef { + c.Lock() + defer c.Unlock() + + var dashboards []*v1alpha1.GrafanaDashboardRef + for _, ds := range c.Dashboards { + dashboards = append(dashboards, ds...) + } + + return dashboards +} + func (c *ControllerConfig) AddConfigItem(key string, value interface{}) { c.Lock() defer c.Unlock() @@ -221,7 +225,7 @@ func (c *ControllerConfig) HasConfigItem(key string) bool { func (c *ControllerConfig) Cleanup(plugins bool) { c.Lock() defer c.Unlock() - c.Dashboards = []*v1alpha1.GrafanaDashboardRef{} + c.Dashboards = map[string][]*v1alpha1.GrafanaDashboardRef{} if plugins { c.Plugins = map[string]v1alpha1.PluginList{} diff --git a/controllers/grafana/grafana_controller.go b/controllers/grafana/grafana_controller.go index c9eab6f1d..54556e489 100644 --- a/controllers/grafana/grafana_controller.go +++ b/controllers/grafana/grafana_controller.go @@ -283,11 +283,7 @@ func (r *ReconcileGrafana) manageSuccess(cr *grafanav1alpha1.Grafana, state *com // Only update the status if the dashboard controller had a chance to sync the cluster // dashboards first. Otherwise reuse the existing dashboard config from the CR. if r.Config.GetConfigBool(config.ConfigGrafanaDashboardsSynced, false) { - cr.Status.InstalledDashboards = r.Config.Dashboards - } else { - if r.Config.Dashboards == nil { - r.Config.SetDashboards([]*grafanav1alpha1.GrafanaDashboardRef{}) - } + cr.Status.InstalledDashboards = r.Config.GetAllDashboards() } instance := &grafanav1alpha1.Grafana{} diff --git a/controllers/grafanadashboard/grafanadashboard_controller.go b/controllers/grafanadashboard/grafanadashboard_controller.go index 9c01f1228..efdbabc68 100644 --- a/controllers/grafanadashboard/grafanadashboard_controller.go +++ b/controllers/grafanadashboard/grafanadashboard_controller.go @@ -363,13 +363,9 @@ func (r *GrafanaDashboardReconciler) reconcileDashboards(request reconcile.Reque log.Log.Info(fmt.Sprintf("delete result was %v", *status.Message)) - r.config.RemovePluginsFor(dashboard.Namespace, dashboard.Name) + r.config.RemovePluginsFor(dashboard) r.config.RemoveDashboard(dashboard.UID) - // Mark the dashboards as synced so that the current state can be written - // to the Grafana CR by the grafana controller - r.config.AddConfigItem(config.ConfigGrafanaDashboardsSynced, true) - // Refresh the list of known dashboards after the dashboard has been removed knownDashboards = r.config.GetDashboards(request.Namespace) @@ -385,6 +381,10 @@ func (r *GrafanaDashboardReconciler) reconcileDashboards(request reconcile.Reque } } + // Mark the dashboards as synced so that the current state can be written + // to the Grafana CR by the grafana controller + r.config.AddConfigItem(config.ConfigGrafanaDashboardsSynced, true) + return reconcile.Result{Requeue: false}, nil }