mirror of
https://github.com/lukaszraczylo/traefik-llmgateway.git
synced 2026-10-17 05:37:43 +00:00
feat(admin): expose group provider/model access
GET /admin/api/usage's group rows now carry the group's configured Providers/Models/MCPServers/Agents (GroupConfig, llmgateway.go), echoed exactly as configured -- never resolved/expanded to the full catalog server-side. Empty/unset stays omitted (omitempty), matching GroupConfig's own JSON convention and group.allowsX's empty-means-all semantics (auth.go): the dashboard can tell 'restricted to these N' apart from 'unrestricted' without the payload growing with catalog size. groupSummary (auth.go) gains providers/models/mcpServers/agents, carried through from authStore.snapshot unchanged. adminUsageEntryView (admin.go) gains the matching JSON fields, populated only for group entries -- a user or the total scope row never carries them, mirroring GroupName's own user-only convention. The Usage view's group accordion (webui/UsageView.vue) renders an Access block above the existing stat grid: Badge chips for explicit providers, ModelChip for explicit models (both shadcn/existing components, no hand-rolled chips), or muted 'All providers'/'All models' text when unrestricted. Display-only this round -- not wired into the user/group search filter. types/api.ts's AdminUsageEntryView mirrors the new optional fields. Tests: admin_test.go's new table-driven TestAdminUsage_GroupAccessLists covers a restricted group's exact lists, an unrestricted group's empty/omitted lists, and that a user/total row never carries them.
This commit is contained in:
@@ -334,10 +334,19 @@ type userSummary struct {
|
||||
|
||||
// groupSummary mirrors userSummary for one configured group, plus its
|
||||
// current member count (how many active users, inline or file-sourced,
|
||||
// currently reference it).
|
||||
// currently reference it) and its configured access lists — providers,
|
||||
// models, mcpServers, agents — carried through exactly as group.allowsX
|
||||
// itself reads them (group-access-display task): nil/empty means every
|
||||
// provider/model/MCP server/agent is allowed (matchesGlob's own contract,
|
||||
// auth.go), never expanded to the full catalog here — the admin dashboard
|
||||
// echoes the configured glob list, not a resolved membership set.
|
||||
type groupSummary struct {
|
||||
limits *LimitsConfig
|
||||
name string
|
||||
providers []string
|
||||
models []string
|
||||
mcpServers []string
|
||||
agents []string
|
||||
memberCount int
|
||||
}
|
||||
|
||||
@@ -359,7 +368,15 @@ func (a *authStore) snapshot() ([]userSummary, []groupSummary) {
|
||||
|
||||
groups := make([]groupSummary, 0, len(a.groups))
|
||||
for name, grp := range a.groups {
|
||||
groups = append(groups, groupSummary{limits: grp.limits, name: name, memberCount: memberCounts[name]})
|
||||
groups = append(groups, groupSummary{
|
||||
limits: grp.limits,
|
||||
name: name,
|
||||
providers: grp.providers,
|
||||
models: grp.models,
|
||||
mcpServers: grp.mcpServers,
|
||||
agents: grp.agents,
|
||||
memberCount: memberCounts[name],
|
||||
})
|
||||
}
|
||||
sort.Slice(groups, func(i, j int) bool { return groups[i].name < groups[j].name })
|
||||
|
||||
|
||||
Reference in New Issue
Block a user