-
Notifications
You must be signed in to change notification settings - Fork 433
Manage Grafana Service Accounts from the Grafana CR #2125
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
Conversation
e2c8577
to
12800fc
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I will leave it this for now and review the remaining functions when I have more time to familiarize myself with the service accounts api :)
5dd705f
to
27ddc60
Compare
2c92519
to
079dbac
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Overall code & flow looks good to me! Left some minor points of improvement but nothing major. Good work @ndk!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If it's not too much to ask, would you include an example of using the new CR under examples/serviceaccounts/
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM! Let's see if @Baarsgaard has any last comments - other than that, I'm happy to merge this
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
While testing this I found a minor oversight, which might be a regression from an earlier version:
The operator currently fails to take ownership if a Service account with the same name already exists in Grafana:
status:
conditions:
- lastTransitionTime: "2025-08-30T21:23:29Z"
message: |-
ServiceAccount failed to be applied for 1 out of 1 instances. Errors:
- grafana: upserting service account: creating service account: [POST /serviceaccounts][400] createServiceAccountBadRequest {"message":"service account already exists"}
observedGeneration: 1
reason: ApplyFailed
status: "False"
type: ServiceAccountSynchronized
Sidenote @theSuess, does it ever make sense to create a GrafanaServiceAccount
with an empty token list?
Currently, if the token list is empty, the operator will delete any manually created tokens as outlined in the Proposal, but is there any use for serviceaccounts that does not contain tokens?
If not, should there be a MinItems
validation on the .spec.tokens
field?
Everything else I tested worked flawlessly! Really nice work @ndk :D |
Last note: |
On the existing service account case. There's no perfect solution. If we take ownership, a simple typo in the name could end up wiping tokens and breaking existing workflows. I'd rather surface the conflict so the user decides what to do. Maybe a flag to control this behavior (takeOwnership: true) could work. As for empty token lists. I'd stick to mirroring Grafana’s API. If someone wants a service account without tokens, why block it? Adding minItems doesn't really help UX, it just limits flexibility. |
We discussed this in the weekly a while back, if I recall correctly, the reasoning is twofold:
I checked the revised proposal and it's included under
Depends on which behaviour is considered more confusing? Where as the opposite would be that they cannot apply the resource without at least one token name defined. |
#1469 · feat: declarative Grafana Service Account management
Design proposal: #003
Why
The Grafana Operator lets you manage Grafana through Kubernetes CRs, but service accounts were still a manual step (GUI or HTTP API). This PR lets you declare SAs in the Grafana CR so the operator can:
What's inside
status.serviceAccounts
and exposes conditions.tests/e2e/grafanaserviceaccount
.Design notes
orgId
defaults to the default organizationOut of scope (for now)
expires
).Known limitations
TODO
CR example