mirror of
https://github.com/grafana/grafana.git
synced 2026-05-04 17:26:21 -04:00
* IAM: Persist team members on the Team resource (step 1)
* Add shared CUE TeamMember + TeamPermission types and expose
TeamSpec.Members as a list of those.
* team LegacyStore: hydrate spec.members on Get/List and reconcile
add/update/delete deltas on Create/Update against the legacy team
tables. Reconciliation runs in the same SQL transaction as the team
row update; team-internal-ID resolution happens before BEGIN to avoid
a SQLite self-deadlock when the write tx holds the file lock.
* Admission rejects duplicate members and flips of the immutable
`external` flag so the error is consistent regardless of dual-write
mode.
* Legacy CreateTeam now returns apierrors.NewAlreadyExists on a unique
constraint violation so clients see a proper 409 instead of a 500
wrapping the raw SQL error.
* Index member UIDs on the Team search document.
* Integration tests cover CRUD with members, hydration, and the new
admission rules.
Scope of this commit is the data model + legacy store + index path.
The user-teams / team-members subresources, the enterprise team-group
synchronizer, and the legacy member-search adapter land in follow-up
steps on this branch.
* Regenerate openapi spec
* IAM: fix testdata path in team integration subtests
The team integration test file lives in `pkg/tests/apis/iam/team/`
while the shared testdata fixtures live one level up in
`pkg/tests/apis/iam/testdata/`. The new members/AlreadyExists subtests
referenced `testdata/…` instead of `../testdata/…`, so CI failed with
"no such file or directory" when loading the fixture. Use the correct
relative path and switch the helper deletions from `defer` to
`t.Cleanup` for consistency with the rest of the file.
* Fix frontend
* IAM: address review on team members path
* Create is now transactional. CreateTeamCommand gained MemberCreates
and legacy.CreateTeam inserts the team row and all seed members in
one WithTransaction; a failing member rolls back the team too,
matching Update's atomicity.
* Update now maps team.ErrTeamMemberAlreadyAdded → apierrors.NewConflict
so the concurrent-add race returns 409 instead of 500, matching the
Create path.
* buildCreateCommand / buildUpdateCommand translate GetUserInternalID
failures into apierrors.NewBadRequest so an unknown user UID in
spec.members returns 400 rather than a 500.
* Replace the per-team hydration on List with a single bulk query via
a new ListTeamBindingsQuery.TeamUIDs + ArgList in team_bindings_query.sql,
backed by listTeamMembersForTeams. Drops the N+1.
* mapTeamPermission / toLegacyPermission use explicit switches with a
default panic so adding a new permission variant upstream without
updating the mapping fails loud instead of silently collapsing to
"member".
* Clarify comments on CreateTeamCommand.MemberCreates and
UpdateTeamCommand.Member{Deletes,Updates,Creates} to spell out the
atomicity guarantee and which fields the caller must pre-resolve.
* Document the remaining TOCTOU gap between listAllTeamMembers and the
write tx in Update, and why the race that matters (add-add) is
covered by the unique-constraint → 409 path.
* IAM: integration test for Update 409 on concurrent member adds
Exercises the ErrTeamMemberAlreadyAdded → apierrors.NewConflict mapping
on the team Update path by racing 10 goroutines that each add the same
user to an empty team. The test asserts no goroutine ever receives a
500 (the pre-fix failure mode), at least one succeeds, and the final
team state contains the user exactly once — i.e. the race converges
through the 409/retry path rather than duplicating or corrupting rows.
* IAM: propagate permission-mapping errors and bulk team-member writes
* mapTeamPermission / toLegacyPermission / mapToTeamMember / toTeamObject
now return (value, error) instead of panicking on unknown variants.
diffMembers, buildCreateCommand, buildUpdateCommand, and the Get /
List / Create / Update flows in team/store.go propagate the error so
a corrupt SQL row or a new upstream variant surfaces as a 500 at the
HTTP boundary instead of crashing the apiserver.
* legacy.CreateTeam and legacy.UpdateTeam now issue one bulk INSERT
(multi-row VALUES) for MemberCreates and one bulk DELETE (… WHERE
uid IN (...)) for MemberDeletes, replacing the per-row loops.
DeleteTeamMembersBulkCommand is scoped by OrgID so a UID collision
across orgs cannot remove the wrong row. Permission UPDATEs stay as
one statement per row — each has a distinct target value and a
CASE-WHEN bulk isn't worth the complexity today.
* New golden-SQL tests (single + many variants) cover the two bulk
templates across mysql/postgres/sqlite.
|
||
|---|---|---|
| .. | ||
| apis | ||
| app | ||