Skip to content

Commit 5dd705f

Browse files
committed
wip
1 parent 98b3ade commit 5dd705f

File tree

1 file changed

+15
-42
lines changed

1 file changed

+15
-42
lines changed

controllers/serviceaccount_controller.go

Lines changed: 15 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -286,63 +286,36 @@ func buildUpdateFormIfNeeded(spec *v1beta1.GrafanaServiceAccountSpec, status *v1
286286
return form
287287
}
288288

289-
// computeGrafanaLogin reconstructs the internal login identifier that Grafana generates for a service account.
290-
//
291-
// Grafana internally uses two fields: 'login' (immutable identifier) and 'name' (display name).
292-
// When creating a service account via API, you only provide 'name', and Grafana generates 'login'
293-
// using the pattern: "sa-{orgID}-{name}". Since we only store the desired name in the CR spec
294-
// and need to find existing accounts, we need to recreate this logic to compute the expected login.
295-
//
296-
// NOTE: This is a workaround that duplicates Grafana's internal logic. Ideally, Grafana would
297-
// support metadata/labels on service accounts or provide direct lookup by name. Until then,
298-
// we rely on this reverse-engineered logic to match accounts.
299-
//
300-
// Borrowed from Grafana: https://github.com/grafana/grafana/blob/e3cb84bef8579db2cead8398b751c5d2c9d563f0/pkg/services/serviceaccounts/database/store.go#L61
301-
func computeGrafanaLogin(orgID int64, name string) string {
302-
const (
303-
serviceAccountPrefix = "sa-"
304-
)
305-
306-
generatedLogin := fmt.Sprintf("%v-%v-%v", serviceAccountPrefix, orgID, strings.ToLower(name))
307-
// in case the name has multiple spaces or dashes in the prefix or otherwise, replace them with a single dash
308-
generatedLogin = strings.Replace(generatedLogin, "--", "-", 1)
309-
310-
return strings.ReplaceAll(generatedLogin, " ", "-")
311-
}
312-
313289
// ensureAccount guarantees that a service account exists in Grafana with the desired name.
314290
// If found, it syncs the account status including tokens. If not found, it creates a new account.
315291
func (r *GrafanaServiceAccountReconciler) ensureAccount(
316292
ctx context.Context,
317293
gClient *genapi.GrafanaHTTPAPI,
318294
cr *v1beta1.GrafanaServiceAccount,
319295
) error {
320-
for page := int64(1); ; page++ {
321-
saList, err := gClient.ServiceAccounts.SearchOrgServiceAccountsWithPaging(
296+
// If we have an ID in status, try to fetch the account directly
297+
if cr.Status.Account != nil && cr.Status.Account.ID > 0 {
298+
retrieve, err := gClient.ServiceAccounts.RetrieveServiceAccountWithParams(
322299
service_accounts.
323-
NewSearchOrgServiceAccountsWithPagingParamsWithContext(ctx).
324-
WithQuery(&cr.Spec.Name).
325-
WithPage(&page),
300+
NewRetrieveServiceAccountParamsWithContext(ctx).
301+
WithServiceAccountID(cr.Status.Account.ID),
326302
)
327-
if err != nil {
328-
return fmt.Errorf("listing service accounts (page %d): %w", page, err)
303+
if err == nil {
304+
return r.populateStatusFromGrafana(ctx, gClient, cr, retrieve.Payload)
329305
}
330306

331-
for _, sa := range saList.Payload.ServiceAccounts {
332-
// TODO: Currently we use OrgID from the returned service accounts, which works
333-
// because we only operate in the default org. When multi-org support is added,
334-
// we should fetch the current org ID from the client to ensure correct matching:
335-
// org, err := gClient.Org.GetCurrentOrgWithParams(...)
336-
if sa.Login == computeGrafanaLogin(sa.OrgID, cr.Spec.Name) {
337-
return r.populateStatusFromGrafana(ctx, gClient, cr, sa)
338-
}
307+
// ATM, service_accounts.RetrieveServiceAccountNotFound doesn't have Is, Unwrap, Unwrap.
308+
// So, we cannot rely only on errors.Is().
309+
_, notFound := err.(*service_accounts.RetrieveServiceAccountNotFound) // nolint:errorlint
310+
if !notFound && !errors.Is(err, service_accounts.NewRetrieveServiceAccountNotFound()) {
311+
return fmt.Errorf("retrieving service account by ID %d: %w", cr.Status.Account.ID, err)
339312
}
340313

341-
if len(saList.Payload.ServiceAccounts) == 0 || (saList.Payload.Page*saList.Payload.PerPage) >= saList.Payload.TotalCount {
342-
break
343-
}
314+
// Service account not found, clear the status and create a new one
315+
cr.Status.Account = nil
344316
}
345317

318+
// No ID in status or account not found, create a new one
346319
if err := r.createAccount(ctx, gClient, cr); err != nil {
347320
return fmt.Errorf("creating service account: %w", err)
348321
}

0 commit comments

Comments
 (0)