Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix organization order when requeuing #197

Merged
merged 2 commits into from
Dec 12, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading