Skip to content

Commit

Permalink
fix organization order when requeuing (#197)
Browse files Browse the repository at this point in the history
* fix organization reordering

* Update grafanaorganization_controller.go

review
  • Loading branch information
QuentinBisson authored Dec 12, 2024
1 parent 9ffd87d commit b094eea
Show file tree
Hide file tree
Showing 2 changed files with 25 additions and 7 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [Unreleased]

### Fixed

- Fix grafana organization reordering.

## [0.10.0] - 2024-12-10

### Added
Expand Down
28 changes: 21 additions & 7 deletions internal/controller/grafanaorganization_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,10 @@ limitations under the License.
package controller

import (
"cmp"
"context"
"fmt"
"slices"
"strings"

grafanaAPI "github.com/grafana/grafana-openapi-client-go/client"
"github.com/pkg/errors"
Expand Down Expand Up @@ -138,6 +138,10 @@ func (r *GrafanaOrganizationReconciler) SetupWithManager(mgr ctrl.Manager) error
return []reconcile.Request{}
}

// Sort organizations by orgID to ensure the order is deterministic.
// This is important to prevent incorrect ordering of organizations on grafana restarts.
slices.SortStableFunc(organizations.Items, compareOrganizationsByID)

// Reconcile all grafana organizations when the grafana pod is recreated
requests := make([]reconcile.Request, 0, len(organizations.Items))
for _, organization := range organizations.Items {
Expand All @@ -154,6 +158,19 @@ func (r *GrafanaOrganizationReconciler) SetupWithManager(mgr ctrl.Manager) error
Complete(r)
}

func compareOrganizationsByID(i, j v1alpha1.GrafanaOrganization) int {
// if both orgs have a nil orgID, they are equal
// if one org has a nil orgID, it is higher than the other as it was not created in Grafana yet
if i.Status.OrgID == 0 && j.Status.OrgID == 0 {
return 0
} else if i.Status.OrgID == 0 {
return 1
} else if j.Status.OrgID == 0 {
return -1
}
return cmp.Compare(i.Status.OrgID, j.Status.OrgID)
}

// reconcileCreate creates the grafanaOrganization.
// reconcileCreate ensures the Grafana organization described in grafanaOrganization CR is created in Grafana.
// This function is also responsible for:
Expand Down Expand Up @@ -368,22 +385,19 @@ func (r *GrafanaOrganizationReconciler) configureGrafana(ctx context.Context) er
}

_, err = controllerutil.CreateOrPatch(ctx, r.Client, grafanaConfig, func() error {
organizations := organizationList.Items
// We always sort the organizations to ensure the order is deterministic and the configmap is stable
// in order to prevent grafana to restarts.
slices.SortFunc(organizations, func(i, j v1alpha1.GrafanaOrganization) int {
return strings.Compare(i.Name, j.Name)
})
slices.SortStableFunc(organizationList.Items, compareOrganizationsByID)

config, err := templating.GenerateGrafanaConfiguration(organizations)
config, err := templating.GenerateGrafanaConfiguration(organizationList.Items)
if err != nil {
logger.Error(err, "failed to generate grafana user configmap values.")
return errors.WithStack(err)
}

// TODO: to be removed for next release
// cleanup owner references from the config map, see https://github.com/giantswarm/observability-operator/pull/183
for _, organization := range organizations {
for _, organization := range organizationList.Items {
// nolint:errcheck,gosec // ignore errors, owner references are probably already gone
controllerutil.RemoveOwnerReference(&organization, grafanaConfig, r.Scheme)
}
Expand Down

0 comments on commit b094eea

Please sign in to comment.