Skip to content

Commit

Permalink
Track dashboards per namespace in ControllerConfig (#690)
Browse files Browse the repository at this point in the history
* Track dashboards per namespace in ControllerConfig

* Remove extra line in generated code

* Fix status update for the Grafana resource

Co-authored-by: Edvin N <edvin.norling@xenit.se>
Co-authored-by: Hubert Stefanski <35736504+HubertStefanski@users.noreply.github.com>
  • Loading branch information
3 people committed Mar 24, 2022
1 parent aa20ca0 commit 0f0e7d1
Show file tree
Hide file tree
Showing 3 changed files with 44 additions and 44 deletions.
72 changes: 38 additions & 34 deletions controllers/config/controller_config.go
Expand Up @@ -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
Expand All @@ -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
Expand Down Expand Up @@ -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(),
Expand All @@ -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(),
Expand All @@ -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
}
}
Expand All @@ -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()
Expand Down Expand Up @@ -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{}
Expand Down
6 changes: 1 addition & 5 deletions controllers/grafana/grafana_controller.go
Expand Up @@ -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{}
Expand Down
10 changes: 5 additions & 5 deletions controllers/grafanadashboard/grafanadashboard_controller.go
Expand Up @@ -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)

Expand All @@ -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
}

Expand Down

0 comments on commit 0f0e7d1

Please sign in to comment.