mirror of
https://github.com/grafana/grafana.git
synced 2025-07-30 07:12:20 +08:00
169 lines
4.4 KiB
Go
169 lines
4.4 KiB
Go
package team
|
|
|
|
import (
|
|
"context"
|
|
"strconv"
|
|
"time"
|
|
|
|
"k8s.io/apimachinery/pkg/apis/meta/internalversion"
|
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
|
"k8s.io/apimachinery/pkg/runtime"
|
|
"k8s.io/apiserver/pkg/registry/rest"
|
|
|
|
claims "github.com/grafana/authlib/types"
|
|
iamv0 "github.com/grafana/grafana/pkg/apis/iam/v0alpha1"
|
|
"github.com/grafana/grafana/pkg/registry/apis/iam/common"
|
|
"github.com/grafana/grafana/pkg/registry/apis/iam/legacy"
|
|
"github.com/grafana/grafana/pkg/services/apiserver/endpoints/request"
|
|
"github.com/grafana/grafana/pkg/services/team"
|
|
)
|
|
|
|
var bindingResource = iamv0.TeamBindingResourceInfo
|
|
|
|
var (
|
|
_ rest.Storage = (*LegacyBindingStore)(nil)
|
|
_ rest.Scoper = (*LegacyBindingStore)(nil)
|
|
_ rest.SingularNameProvider = (*LegacyBindingStore)(nil)
|
|
_ rest.Getter = (*LegacyBindingStore)(nil)
|
|
_ rest.Lister = (*LegacyBindingStore)(nil)
|
|
)
|
|
|
|
func NewLegacyBindingStore(store legacy.LegacyIdentityStore) *LegacyBindingStore {
|
|
return &LegacyBindingStore{store}
|
|
}
|
|
|
|
type LegacyBindingStore struct {
|
|
store legacy.LegacyIdentityStore
|
|
}
|
|
|
|
// Destroy implements rest.Storage.
|
|
func (l *LegacyBindingStore) Destroy() {}
|
|
|
|
// New implements rest.Storage.
|
|
func (l *LegacyBindingStore) New() runtime.Object {
|
|
return bindingResource.NewFunc()
|
|
}
|
|
|
|
// NewList implements rest.Lister.
|
|
func (l *LegacyBindingStore) NewList() runtime.Object {
|
|
return bindingResource.NewListFunc()
|
|
}
|
|
|
|
// NamespaceScoped implements rest.Scoper.
|
|
func (l *LegacyBindingStore) NamespaceScoped() bool {
|
|
return true
|
|
}
|
|
|
|
// GetSingularName implements rest.SingularNameProvider.
|
|
func (l *LegacyBindingStore) GetSingularName() string {
|
|
return bindingResource.GetSingularName()
|
|
}
|
|
|
|
// ConvertToTable implements rest.Lister.
|
|
func (l *LegacyBindingStore) ConvertToTable(ctx context.Context, object runtime.Object, tableOptions runtime.Object) (*metav1.Table, error) {
|
|
return bindingResource.TableConverter().ConvertToTable(ctx, object, tableOptions)
|
|
}
|
|
|
|
// Get implements rest.Getter.
|
|
func (l *LegacyBindingStore) Get(ctx context.Context, name string, options *metav1.GetOptions) (runtime.Object, error) {
|
|
ns, err := request.NamespaceInfoFrom(ctx, true)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
res, err := l.store.ListTeamBindings(ctx, ns, legacy.ListTeamBindingsQuery{
|
|
UID: name,
|
|
Pagination: common.Pagination{Limit: 1},
|
|
})
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
if len(res.Bindings) != 1 {
|
|
// FIXME: maybe empty result?
|
|
return nil, resource.NewNotFound(name)
|
|
}
|
|
|
|
obj := mapToBindingObject(ns, res.Bindings[0])
|
|
return &obj, nil
|
|
}
|
|
|
|
// List implements rest.Lister.
|
|
func (l *LegacyBindingStore) List(ctx context.Context, options *internalversion.ListOptions) (runtime.Object, error) {
|
|
ns, err := request.NamespaceInfoFrom(ctx, true)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
res, err := l.store.ListTeamBindings(ctx, ns, legacy.ListTeamBindingsQuery{
|
|
Pagination: common.PaginationFromListOptions(options),
|
|
})
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
list := iamv0.TeamBindingList{
|
|
Items: make([]iamv0.TeamBinding, 0, len(res.Bindings)),
|
|
}
|
|
|
|
for _, b := range res.Bindings {
|
|
list.Items = append(list.Items, mapToBindingObject(ns, b))
|
|
}
|
|
|
|
list.Continue = common.OptionalFormatInt(res.Continue)
|
|
list.ResourceVersion = common.OptionalFormatInt(res.RV)
|
|
|
|
return &list, nil
|
|
}
|
|
|
|
func mapToBindingObject(ns claims.NamespaceInfo, b legacy.TeamBinding) iamv0.TeamBinding {
|
|
rv := time.Time{}
|
|
ct := time.Now()
|
|
|
|
for _, m := range b.Members {
|
|
if m.Updated.After(rv) {
|
|
rv = m.Updated
|
|
}
|
|
if m.Created.Before(ct) {
|
|
ct = m.Created
|
|
}
|
|
}
|
|
|
|
return iamv0.TeamBinding{
|
|
ObjectMeta: metav1.ObjectMeta{
|
|
Name: b.TeamUID,
|
|
Namespace: ns.Value,
|
|
ResourceVersion: strconv.FormatInt(rv.UnixMilli(), 10),
|
|
CreationTimestamp: metav1.NewTime(ct),
|
|
},
|
|
Spec: iamv0.TeamBindingSpec{
|
|
Team: iamv0.TeamRef{
|
|
Name: b.TeamUID,
|
|
},
|
|
Subjects: mapToSubjects(b.Members),
|
|
},
|
|
}
|
|
}
|
|
|
|
func mapToSubjects(members []legacy.TeamMember) []iamv0.TeamSubject {
|
|
out := make([]iamv0.TeamSubject, 0, len(members))
|
|
for _, m := range members {
|
|
out = append(out, iamv0.TeamSubject{
|
|
Identity: iamv0.IdentityRef{
|
|
Type: claims.TypeUser,
|
|
Name: m.UserUID,
|
|
},
|
|
Permission: common.MapTeamPermission(m.Permission),
|
|
})
|
|
}
|
|
return out
|
|
}
|
|
|
|
func mapPermisson(p team.PermissionType) iamv0.TeamPermission {
|
|
if p == team.PermissionTypeAdmin {
|
|
return iamv0.TeamPermissionAdmin
|
|
} else {
|
|
return iamv0.TeamPermissionMember
|
|
}
|
|
}
|