From 069431734ae576dd3790607fc4cfea18c6fb1c10 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andreas=20M=C3=A5rtensson?= Date: Fri, 17 Dec 2021 16:15:53 +0100 Subject: [PATCH 1/3] Track dashboards per namespace in ControllerConfig --- .../v1alpha1/zz_generated.deepcopy.go | 1 + controllers/config/controller_config.go | 62 +++++++++++-------- controllers/grafana/grafana_controller.go | 4 +- .../grafanadashboard_controller.go | 2 +- 4 files changed, 41 insertions(+), 28 deletions(-) diff --git a/api/integreatly/v1alpha1/zz_generated.deepcopy.go b/api/integreatly/v1alpha1/zz_generated.deepcopy.go index 10b78df33..d07f415f1 100644 --- a/api/integreatly/v1alpha1/zz_generated.deepcopy.go +++ b/api/integreatly/v1alpha1/zz_generated.deepcopy.go @@ -1,3 +1,4 @@ +//go:build !ignore_autogenerated // +build !ignore_autogenerated /* diff --git a/controllers/config/controller_config.go b/controllers/config/controller_config.go index de49222ee..9f0ed18ac 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,25 +130,35 @@ 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) { +func (c *ControllerConfig) SetDashboards(ns string, dashboards []*v1alpha1.GrafanaDashboardRef) { c.Lock() defer c.Unlock() - c.Dashboards = dashboards + if ns == "" { + for nss := range c.Dashboards { + c.Dashboards[nss] = dashboards + } + } else { + c.Dashboards[ns] = 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 + } } } @@ -158,13 +168,15 @@ func (c *ControllerConfig) GetDashboards(namespace string) []*v1alpha1.GrafanaDa // Checking for dashboards at the cluster level? across namespaces? if namespace == "" { var dashboards []*v1alpha1.GrafanaDashboardRef - dashboards = append(dashboards, c.Dashboards...) + for _, ds := range c.Dashboards { + dashboards = append(dashboards, ds...) + } return dashboards } - if c.Dashboards != nil { - return c.Dashboards + if c.Dashboards[namespace] != nil { + return c.Dashboards[namespace] } return []*v1alpha1.GrafanaDashboardRef{} } @@ -221,7 +233,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..977d33ea1 100644 --- a/controllers/grafana/grafana_controller.go +++ b/controllers/grafana/grafana_controller.go @@ -283,10 +283,10 @@ 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 + cr.Status.InstalledDashboards = r.Config.GetDashboards(request.Namespace) } else { if r.Config.Dashboards == nil { - r.Config.SetDashboards([]*grafanav1alpha1.GrafanaDashboardRef{}) + r.Config.SetDashboards(request.Namespace, []*grafanav1alpha1.GrafanaDashboardRef{}) } } diff --git a/controllers/grafanadashboard/grafanadashboard_controller.go b/controllers/grafanadashboard/grafanadashboard_controller.go index 9c01f1228..0db294c67 100644 --- a/controllers/grafanadashboard/grafanadashboard_controller.go +++ b/controllers/grafanadashboard/grafanadashboard_controller.go @@ -363,7 +363,7 @@ 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 From 7b4181628eb6682894f53b2a1959093fe6666391 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andreas=20M=C3=A5rtensson?= Date: Sat, 26 Feb 2022 18:28:04 +0100 Subject: [PATCH 2/3] Remove extra line in generated code --- api/integreatly/v1alpha1/zz_generated.deepcopy.go | 1 - 1 file changed, 1 deletion(-) diff --git a/api/integreatly/v1alpha1/zz_generated.deepcopy.go b/api/integreatly/v1alpha1/zz_generated.deepcopy.go index d07f415f1..10b78df33 100644 --- a/api/integreatly/v1alpha1/zz_generated.deepcopy.go +++ b/api/integreatly/v1alpha1/zz_generated.deepcopy.go @@ -1,4 +1,3 @@ -//go:build !ignore_autogenerated // +build !ignore_autogenerated /* From a579731b76631cc64634a7531310712131ce060c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andreas=20M=C3=A5rtensson?= Date: Wed, 2 Mar 2022 20:39:18 +0100 Subject: [PATCH 3/3] Fix status update for the Grafana resource --- controllers/config/controller_config.go | 34 +++++++------------ controllers/grafana/grafana_controller.go | 6 +--- .../grafanadashboard_controller.go | 8 ++--- 3 files changed, 18 insertions(+), 30 deletions(-) diff --git a/controllers/config/controller_config.go b/controllers/config/controller_config.go index 9f0ed18ac..4cc1590d1 100644 --- a/controllers/config/controller_config.go +++ b/controllers/config/controller_config.go @@ -137,18 +137,6 @@ func (c *ControllerConfig) InvalidateDashboards() { } } -func (c *ControllerConfig) SetDashboards(ns string, dashboards []*v1alpha1.GrafanaDashboardRef) { - c.Lock() - defer c.Unlock() - if ns == "" { - for nss := range c.Dashboards { - c.Dashboards[nss] = dashboards - } - } else { - c.Dashboards[ns] = dashboards - } -} - func (c *ControllerConfig) RemoveDashboard(hash string) { for ns := range c.Dashboards { if i, exists := c.HasDashboard(ns, hash); exists { @@ -165,22 +153,26 @@ func (c *ControllerConfig) RemoveDashboard(hash string) { 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 - for _, ds := range c.Dashboards { - dashboards = append(dashboards, ds...) - } - - return dashboards - } if c.Dashboards[namespace] != nil { return c.Dashboards[namespace] } + 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() diff --git a/controllers/grafana/grafana_controller.go b/controllers/grafana/grafana_controller.go index 977d33ea1..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.GetDashboards(request.Namespace) - } else { - if r.Config.Dashboards == nil { - r.Config.SetDashboards(request.Namespace, []*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 0db294c67..efdbabc68 100644 --- a/controllers/grafanadashboard/grafanadashboard_controller.go +++ b/controllers/grafanadashboard/grafanadashboard_controller.go @@ -366,10 +366,6 @@ func (r *GrafanaDashboardReconciler) reconcileDashboards(request reconcile.Reque 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 }