mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
ServiceAccount: Update service account api resource and add service account token (#92972)
* Create own legacy store function to list service accounts and update api model * Add service account tokens as a sub resource for service accounts
This commit is contained in:
@@ -3,7 +3,7 @@ package common
|
||||
import (
|
||||
"strconv"
|
||||
|
||||
identityv0 "github.com/grafana/grafana/pkg/apis/iam/v0alpha1"
|
||||
iamv0 "github.com/grafana/grafana/pkg/apis/iam/v0alpha1"
|
||||
"github.com/grafana/grafana/pkg/services/team"
|
||||
)
|
||||
|
||||
@@ -16,10 +16,10 @@ func OptionalFormatInt(num int64) string {
|
||||
return ""
|
||||
}
|
||||
|
||||
func MapTeamPermission(p team.PermissionType) identityv0.TeamPermission {
|
||||
func MapTeamPermission(p team.PermissionType) iamv0.TeamPermission {
|
||||
if p == team.PermissionTypeAdmin {
|
||||
return identityv0.TeamPermissionAdmin
|
||||
return iamv0.TeamPermissionAdmin
|
||||
} else {
|
||||
return identityv0.TeamPermissionMember
|
||||
return iamv0.TeamPermissionMember
|
||||
}
|
||||
}
|
||||
|
||||
205
pkg/registry/apis/iam/legacy/service_account.go
Normal file
205
pkg/registry/apis/iam/legacy/service_account.go
Normal file
@@ -0,0 +1,205 @@
|
||||
package legacy
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"github.com/grafana/authlib/claims"
|
||||
"github.com/grafana/grafana/pkg/registry/apis/iam/common"
|
||||
"github.com/grafana/grafana/pkg/storage/legacysql"
|
||||
"github.com/grafana/grafana/pkg/storage/unified/sql/sqltemplate"
|
||||
)
|
||||
|
||||
type ListServiceAccountsQuery struct {
|
||||
UID string
|
||||
OrgID int64
|
||||
Pagination common.Pagination
|
||||
}
|
||||
|
||||
type ListServiceAccountResult struct {
|
||||
Items []ServiceAccount
|
||||
Continue int64
|
||||
RV int64
|
||||
}
|
||||
|
||||
type ServiceAccount struct {
|
||||
ID int64
|
||||
UID string
|
||||
Name string
|
||||
Disabled bool
|
||||
Created time.Time
|
||||
Updated time.Time
|
||||
}
|
||||
|
||||
var sqlQueryServiceAccountsTemplate = mustTemplate("service_accounts_query.sql")
|
||||
|
||||
func newListServiceAccounts(sql *legacysql.LegacyDatabaseHelper, q *ListServiceAccountsQuery) listServiceAccountsQuery {
|
||||
return listServiceAccountsQuery{
|
||||
SQLTemplate: sqltemplate.New(sql.DialectForDriver()),
|
||||
UserTable: sql.Table("user"),
|
||||
OrgUserTable: sql.Table("org_user"),
|
||||
Query: q,
|
||||
}
|
||||
}
|
||||
|
||||
type listServiceAccountsQuery struct {
|
||||
sqltemplate.SQLTemplate
|
||||
Query *ListServiceAccountsQuery
|
||||
UserTable string
|
||||
OrgUserTable string
|
||||
}
|
||||
|
||||
func (r listServiceAccountsQuery) Validate() error {
|
||||
return nil // TODO
|
||||
}
|
||||
|
||||
func (s *legacySQLStore) ListServiceAccounts(ctx context.Context, ns claims.NamespaceInfo, query ListServiceAccountsQuery) (*ListServiceAccountResult, error) {
|
||||
// for continue
|
||||
query.Pagination.Limit += 1
|
||||
query.OrgID = ns.OrgID
|
||||
if ns.OrgID == 0 {
|
||||
return nil, fmt.Errorf("expected non zero orgID")
|
||||
}
|
||||
|
||||
sql, err := s.sql(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
req := newListServiceAccounts(sql, &query)
|
||||
q, err := sqltemplate.Execute(sqlQueryServiceAccountsTemplate, req)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("execute template %q: %w", sqlQueryServiceAccountsTemplate.Name(), err)
|
||||
}
|
||||
|
||||
rows, err := sql.DB.GetSqlxSession().Query(ctx, q, req.GetArgs()...)
|
||||
defer func() {
|
||||
if rows != nil {
|
||||
_ = rows.Close()
|
||||
}
|
||||
}()
|
||||
|
||||
res := &ListServiceAccountResult{}
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var lastID int64
|
||||
for rows.Next() {
|
||||
var s ServiceAccount
|
||||
err := rows.Scan(&s.ID, &s.UID, &s.Name, &s.Disabled, &s.Created, &s.Updated)
|
||||
if err != nil {
|
||||
return res, err
|
||||
}
|
||||
|
||||
lastID = s.ID
|
||||
res.Items = append(res.Items, s)
|
||||
if len(res.Items) > int(query.Pagination.Limit)-1 {
|
||||
res.Items = res.Items[0 : len(res.Items)-1]
|
||||
res.Continue = lastID
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if query.UID == "" {
|
||||
// FIXME: we need to filer for service accounts here..
|
||||
res.RV, err = sql.GetResourceVersion(ctx, "user", "updated")
|
||||
}
|
||||
|
||||
return res, err
|
||||
}
|
||||
|
||||
type ListServiceAccountTokenQuery struct {
|
||||
// UID is the service account uid.
|
||||
UID string
|
||||
OrgID int64
|
||||
Pagination common.Pagination
|
||||
}
|
||||
|
||||
type ListServiceAccountTokenResult struct {
|
||||
Items []ServiceAccountToken
|
||||
Continue int64
|
||||
RV int64
|
||||
}
|
||||
|
||||
type ServiceAccountToken struct {
|
||||
ID int64
|
||||
Name string
|
||||
Revoked bool
|
||||
Expires *int64
|
||||
LastUsed *time.Time
|
||||
Created time.Time
|
||||
Updated time.Time
|
||||
}
|
||||
|
||||
var sqlQueryServiceAccountTokensTemplate = mustTemplate("service_account_tokens_query.sql")
|
||||
|
||||
func newListServiceAccountTokens(sql *legacysql.LegacyDatabaseHelper, q *ListServiceAccountTokenQuery) listServiceAccountTokensQuery {
|
||||
return listServiceAccountTokensQuery{
|
||||
SQLTemplate: sqltemplate.New(sql.DialectForDriver()),
|
||||
UserTable: sql.Table("user"),
|
||||
OrgUserTable: sql.Table("org_user"),
|
||||
TokenTable: sql.Table("api_key"),
|
||||
Query: q,
|
||||
}
|
||||
}
|
||||
|
||||
type listServiceAccountTokensQuery struct {
|
||||
sqltemplate.SQLTemplate
|
||||
Query *ListServiceAccountTokenQuery
|
||||
UserTable string
|
||||
TokenTable string
|
||||
OrgUserTable string
|
||||
}
|
||||
|
||||
func (s *legacySQLStore) ListServiceAccountTokens(ctx context.Context, ns claims.NamespaceInfo, query ListServiceAccountTokenQuery) (*ListServiceAccountTokenResult, error) {
|
||||
// for continue
|
||||
query.Pagination.Limit += 1
|
||||
query.OrgID = ns.OrgID
|
||||
if ns.OrgID == 0 {
|
||||
return nil, fmt.Errorf("expected non zero orgID")
|
||||
}
|
||||
|
||||
sql, err := s.sql(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
req := newListServiceAccountTokens(sql, &query)
|
||||
q, err := sqltemplate.Execute(sqlQueryServiceAccountTokensTemplate, req)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("execute template %q: %w", sqlQueryServiceAccountTokensTemplate.Name(), err)
|
||||
}
|
||||
|
||||
rows, err := sql.DB.GetSqlxSession().Query(ctx, q, req.GetArgs()...)
|
||||
defer func() {
|
||||
if rows != nil {
|
||||
_ = rows.Close()
|
||||
}
|
||||
}()
|
||||
|
||||
res := &ListServiceAccountTokenResult{}
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var lastID int64
|
||||
for rows.Next() {
|
||||
var t ServiceAccountToken
|
||||
err := rows.Scan(&t.ID, &t.Name, &t.Revoked, &t.LastUsed, &t.Expires, &t.Created, &t.Updated)
|
||||
if err != nil {
|
||||
return res, err
|
||||
}
|
||||
|
||||
lastID = t.ID
|
||||
res.Items = append(res.Items, t)
|
||||
if len(res.Items) > int(query.Pagination.Limit)-1 {
|
||||
res.Items = res.Items[0 : len(res.Items)-1]
|
||||
res.Continue = lastID
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
return res, err
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
SELECT
|
||||
t.id,
|
||||
t.name,
|
||||
t.is_revoked,
|
||||
t.last_used_at,
|
||||
t.expires,
|
||||
t.created,
|
||||
t.updated
|
||||
FROM {{ .Ident .TokenTable }} as t
|
||||
INNER JOIN {{ .Ident .UserTable }} as u ON t.service_account_id = u.id
|
||||
INNER JOIN {{ .Ident .OrgUserTable }} as o ON u.id = o.user_id
|
||||
WHERE o.org_id = {{ .Arg .Query.OrgID }}
|
||||
AND u.is_service_account
|
||||
AND u.uid = {{ .Arg .Query.UID }}
|
||||
{{ if .Query.Pagination.Continue }}
|
||||
AND t.id >= {{ .Arg .Query.Pagination.Continue }}
|
||||
{{ end }}
|
||||
ORDER BY t.id asc
|
||||
LIMIT {{ .Arg .Query.Pagination.Limit }}
|
||||
18
pkg/registry/apis/iam/legacy/service_accounts_query.sql
Normal file
18
pkg/registry/apis/iam/legacy/service_accounts_query.sql
Normal file
@@ -0,0 +1,18 @@
|
||||
SELECT
|
||||
u.id,
|
||||
u.uid,
|
||||
u.name,
|
||||
u.is_disabled,
|
||||
u.created,
|
||||
u.updated
|
||||
FROM {{ .Ident .UserTable }} as u JOIN {{ .Ident .OrgUserTable }} as o ON u.id = o.user_id
|
||||
WHERE o.org_id = {{ .Arg .Query.OrgID }}
|
||||
AND u.is_service_account
|
||||
{{ if .Query.UID }}
|
||||
AND u.uid = {{ .Arg .Query.UID }}
|
||||
{{ end }}
|
||||
{{ if .Query.Pagination.Continue }}
|
||||
AND u.id >= {{ .Arg .Query.Pagination.Continue }}
|
||||
{{ end }}
|
||||
ORDER BY u.id asc
|
||||
LIMIT {{ .Arg .Query.Pagination.Limit }}
|
||||
@@ -17,6 +17,9 @@ type LegacyIdentityStore interface {
|
||||
ListUsers(ctx context.Context, ns claims.NamespaceInfo, query ListUserQuery) (*ListUserResult, error)
|
||||
ListUserTeams(ctx context.Context, ns claims.NamespaceInfo, query ListUserTeamsQuery) (*ListUserTeamsResult, error)
|
||||
|
||||
ListServiceAccounts(ctx context.Context, ns claims.NamespaceInfo, query ListServiceAccountsQuery) (*ListServiceAccountResult, error)
|
||||
ListServiceAccountTokens(ctx context.Context, ns claims.NamespaceInfo, query ListServiceAccountTokenQuery) (*ListServiceAccountTokenResult, error)
|
||||
|
||||
ListTeams(ctx context.Context, ns claims.NamespaceInfo, query ListTeamQuery) (*ListTeamResult, error)
|
||||
ListTeamBindings(ctx context.Context, ns claims.NamespaceInfo, query ListTeamBindingsQuery) (*ListTeamBindingsResult, error)
|
||||
ListTeamMembers(ctx context.Context, ns claims.NamespaceInfo, query ListTeamMembersQuery) (*ListTeamMembersResult, error)
|
||||
|
||||
@@ -2,6 +2,6 @@ SELECT o.org_id, u.id, u.uid, u.login, u.email, u.name,
|
||||
u.created, u.updated, u.is_service_account, u.is_disabled, u.is_admin
|
||||
FROM `grafana`.`user` as u JOIN `grafana`.`org_user` as o ON u.id = o.user_id
|
||||
WHERE o.org_id = 0
|
||||
AND u.is_service_account = FALSE
|
||||
AND NOT u.is_service_account
|
||||
ORDER BY u.id asc
|
||||
LIMIT 5
|
||||
|
||||
@@ -2,7 +2,7 @@ SELECT o.org_id, u.id, u.uid, u.login, u.email, u.name,
|
||||
u.created, u.updated, u.is_service_account, u.is_disabled, u.is_admin
|
||||
FROM `grafana`.`user` as u JOIN `grafana`.`org_user` as o ON u.id = o.user_id
|
||||
WHERE o.org_id = 0
|
||||
AND u.is_service_account = FALSE
|
||||
AND NOT u.is_service_account
|
||||
AND u.id >= 2
|
||||
ORDER BY u.id asc
|
||||
LIMIT 1
|
||||
|
||||
@@ -2,7 +2,7 @@ SELECT o.org_id, u.id, u.uid, u.login, u.email, u.name,
|
||||
u.created, u.updated, u.is_service_account, u.is_disabled, u.is_admin
|
||||
FROM `grafana`.`user` as u JOIN `grafana`.`org_user` as o ON u.id = o.user_id
|
||||
WHERE o.org_id = 0
|
||||
AND u.is_service_account = FALSE
|
||||
AND NOT u.is_service_account
|
||||
AND u.uid = 'abc'
|
||||
ORDER BY u.id asc
|
||||
LIMIT 1
|
||||
|
||||
@@ -2,6 +2,6 @@ SELECT o.org_id, u.id, u.uid, u.login, u.email, u.name,
|
||||
u.created, u.updated, u.is_service_account, u.is_disabled, u.is_admin
|
||||
FROM "grafana"."user" as u JOIN "grafana"."org_user" as o ON u.id = o.user_id
|
||||
WHERE o.org_id = 0
|
||||
AND u.is_service_account = FALSE
|
||||
AND NOT u.is_service_account
|
||||
ORDER BY u.id asc
|
||||
LIMIT 5
|
||||
|
||||
@@ -2,7 +2,7 @@ SELECT o.org_id, u.id, u.uid, u.login, u.email, u.name,
|
||||
u.created, u.updated, u.is_service_account, u.is_disabled, u.is_admin
|
||||
FROM "grafana"."user" as u JOIN "grafana"."org_user" as o ON u.id = o.user_id
|
||||
WHERE o.org_id = 0
|
||||
AND u.is_service_account = FALSE
|
||||
AND NOT u.is_service_account
|
||||
AND u.id >= 2
|
||||
ORDER BY u.id asc
|
||||
LIMIT 1
|
||||
|
||||
@@ -2,7 +2,7 @@ SELECT o.org_id, u.id, u.uid, u.login, u.email, u.name,
|
||||
u.created, u.updated, u.is_service_account, u.is_disabled, u.is_admin
|
||||
FROM "grafana"."user" as u JOIN "grafana"."org_user" as o ON u.id = o.user_id
|
||||
WHERE o.org_id = 0
|
||||
AND u.is_service_account = FALSE
|
||||
AND NOT u.is_service_account
|
||||
AND u.uid = 'abc'
|
||||
ORDER BY u.id asc
|
||||
LIMIT 1
|
||||
|
||||
@@ -2,6 +2,6 @@ SELECT o.org_id, u.id, u.uid, u.login, u.email, u.name,
|
||||
u.created, u.updated, u.is_service_account, u.is_disabled, u.is_admin
|
||||
FROM "grafana"."user" as u JOIN "grafana"."org_user" as o ON u.id = o.user_id
|
||||
WHERE o.org_id = 0
|
||||
AND u.is_service_account = FALSE
|
||||
AND NOT u.is_service_account
|
||||
ORDER BY u.id asc
|
||||
LIMIT 5
|
||||
|
||||
@@ -2,7 +2,7 @@ SELECT o.org_id, u.id, u.uid, u.login, u.email, u.name,
|
||||
u.created, u.updated, u.is_service_account, u.is_disabled, u.is_admin
|
||||
FROM "grafana"."user" as u JOIN "grafana"."org_user" as o ON u.id = o.user_id
|
||||
WHERE o.org_id = 0
|
||||
AND u.is_service_account = FALSE
|
||||
AND NOT u.is_service_account
|
||||
AND u.id >= 2
|
||||
ORDER BY u.id asc
|
||||
LIMIT 1
|
||||
|
||||
@@ -2,7 +2,7 @@ SELECT o.org_id, u.id, u.uid, u.login, u.email, u.name,
|
||||
u.created, u.updated, u.is_service_account, u.is_disabled, u.is_admin
|
||||
FROM "grafana"."user" as u JOIN "grafana"."org_user" as o ON u.id = o.user_id
|
||||
WHERE o.org_id = 0
|
||||
AND u.is_service_account = FALSE
|
||||
AND NOT u.is_service_account
|
||||
AND u.uid = 'abc'
|
||||
ORDER BY u.id asc
|
||||
LIMIT 1
|
||||
|
||||
@@ -14,9 +14,8 @@ import (
|
||||
)
|
||||
|
||||
type ListUserQuery struct {
|
||||
OrgID int64
|
||||
UID string
|
||||
IsServiceAccount bool
|
||||
OrgID int64
|
||||
UID string
|
||||
|
||||
Pagination common.Pagination
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@ SELECT o.org_id, u.id, u.uid, u.login, u.email, u.name,
|
||||
u.created, u.updated, u.is_service_account, u.is_disabled, u.is_admin
|
||||
FROM {{ .Ident .UserTable }} as u JOIN {{ .Ident .OrgUserTable }} as o ON u.id = o.user_id
|
||||
WHERE o.org_id = {{ .Arg .Query.OrgID }}
|
||||
AND u.is_service_account = {{ .Arg .Query.IsServiceAccount }}
|
||||
AND NOT u.is_service_account
|
||||
{{ if .Query.UID }}
|
||||
AND u.uid = {{ .Arg .Query.UID }}
|
||||
{{ end }}
|
||||
|
||||
@@ -4,7 +4,7 @@ import (
|
||||
"context"
|
||||
|
||||
"github.com/grafana/grafana/pkg/apimachinery/identity"
|
||||
identityv0 "github.com/grafana/grafana/pkg/apis/iam/v0alpha1"
|
||||
iamv0 "github.com/grafana/grafana/pkg/apis/iam/v0alpha1"
|
||||
grafanarest "github.com/grafana/grafana/pkg/apiserver/rest"
|
||||
"github.com/grafana/grafana/pkg/infra/db"
|
||||
"github.com/grafana/grafana/pkg/registry/apis/iam/legacy"
|
||||
@@ -55,19 +55,19 @@ func RegisterAPIService(
|
||||
}
|
||||
|
||||
func (b *IdentityAccessManagementAPIBuilder) GetGroupVersion() schema.GroupVersion {
|
||||
return identityv0.SchemeGroupVersion
|
||||
return iamv0.SchemeGroupVersion
|
||||
}
|
||||
|
||||
func (b *IdentityAccessManagementAPIBuilder) InstallSchema(scheme *runtime.Scheme) error {
|
||||
identityv0.AddKnownTypes(scheme, identityv0.VERSION)
|
||||
iamv0.AddKnownTypes(scheme, iamv0.VERSION)
|
||||
|
||||
// Link this version to the internal representation.
|
||||
// This is used for server-side-apply (PATCH), and avoids the error:
|
||||
// "no kind is registered for the type"
|
||||
identityv0.AddKnownTypes(scheme, runtime.APIVersionInternal)
|
||||
iamv0.AddKnownTypes(scheme, runtime.APIVersionInternal)
|
||||
|
||||
metav1.AddToGroupVersion(scheme, identityv0.SchemeGroupVersion)
|
||||
return scheme.SetVersionPriority(identityv0.SchemeGroupVersion)
|
||||
metav1.AddToGroupVersion(scheme, iamv0.SchemeGroupVersion)
|
||||
return scheme.SetVersionPriority(iamv0.SchemeGroupVersion)
|
||||
}
|
||||
|
||||
func (b *IdentityAccessManagementAPIBuilder) GetAPIGroupInfo(
|
||||
@@ -76,37 +76,38 @@ func (b *IdentityAccessManagementAPIBuilder) GetAPIGroupInfo(
|
||||
optsGetter generic.RESTOptionsGetter,
|
||||
dualWriteBuilder grafanarest.DualWriteBuilder,
|
||||
) (*genericapiserver.APIGroupInfo, error) {
|
||||
apiGroupInfo := genericapiserver.NewDefaultAPIGroupInfo(identityv0.GROUP, scheme, metav1.ParameterCodec, codecs)
|
||||
apiGroupInfo := genericapiserver.NewDefaultAPIGroupInfo(iamv0.GROUP, scheme, metav1.ParameterCodec, codecs)
|
||||
storage := map[string]rest.Storage{}
|
||||
|
||||
teamResource := identityv0.TeamResourceInfo
|
||||
teamResource := iamv0.TeamResourceInfo
|
||||
storage[teamResource.StoragePath()] = team.NewLegacyStore(b.Store)
|
||||
storage[teamResource.StoragePath("members")] = team.NewLegacyTeamMemberREST(b.Store)
|
||||
|
||||
teamBindingResource := identityv0.TeamBindingResourceInfo
|
||||
teamBindingResource := iamv0.TeamBindingResourceInfo
|
||||
storage[teamBindingResource.StoragePath()] = team.NewLegacyBindingStore(b.Store)
|
||||
|
||||
userResource := identityv0.UserResourceInfo
|
||||
userResource := iamv0.UserResourceInfo
|
||||
storage[userResource.StoragePath()] = user.NewLegacyStore(b.Store)
|
||||
storage[userResource.StoragePath("teams")] = user.NewLegacyTeamMemberREST(b.Store)
|
||||
|
||||
serviceaccountResource := identityv0.ServiceAccountResourceInfo
|
||||
serviceaccountResource := iamv0.ServiceAccountResourceInfo
|
||||
storage[serviceaccountResource.StoragePath()] = serviceaccount.NewLegacyStore(b.Store)
|
||||
storage[serviceaccountResource.StoragePath("tokens")] = serviceaccount.NewLegacyTokenREST(b.Store)
|
||||
|
||||
if b.SSOService != nil {
|
||||
ssoResource := identityv0.SSOSettingResourceInfo
|
||||
ssoResource := iamv0.SSOSettingResourceInfo
|
||||
storage[ssoResource.StoragePath()] = sso.NewLegacyStore(b.SSOService)
|
||||
}
|
||||
|
||||
// The display endpoint -- NOTE, this uses a rewrite hack to allow requests without a name parameter
|
||||
storage["display"] = user.NewLegacyDisplayREST(b.Store)
|
||||
|
||||
apiGroupInfo.VersionedResourcesStorageMap[identityv0.VERSION] = storage
|
||||
apiGroupInfo.VersionedResourcesStorageMap[iamv0.VERSION] = storage
|
||||
return &apiGroupInfo, nil
|
||||
}
|
||||
|
||||
func (b *IdentityAccessManagementAPIBuilder) GetOpenAPIDefinitions() common.GetOpenAPIDefinitions {
|
||||
return identityv0.GetOpenAPIDefinitions
|
||||
return iamv0.GetOpenAPIDefinitions
|
||||
}
|
||||
|
||||
func (b *IdentityAccessManagementAPIBuilder) GetAPIRoutes() *builder.APIRoutes {
|
||||
|
||||
115
pkg/registry/apis/iam/serviceaccount/rest_token.go
Normal file
115
pkg/registry/apis/iam/serviceaccount/rest_token.go
Normal file
@@ -0,0 +1,115 @@
|
||||
package serviceaccount
|
||||
|
||||
import (
|
||||
"context"
|
||||
"net/http"
|
||||
"time"
|
||||
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/apiserver/pkg/registry/rest"
|
||||
|
||||
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"
|
||||
)
|
||||
|
||||
var (
|
||||
_ rest.Storage = (*LegacyTokenRest)(nil)
|
||||
_ rest.Scoper = (*LegacyTokenRest)(nil)
|
||||
_ rest.StorageMetadata = (*LegacyTokenRest)(nil)
|
||||
_ rest.Connecter = (*LegacyTokenRest)(nil)
|
||||
)
|
||||
|
||||
func NewLegacyTokenREST(store legacy.LegacyIdentityStore) *LegacyTokenRest {
|
||||
return &LegacyTokenRest{store}
|
||||
}
|
||||
|
||||
type LegacyTokenRest struct {
|
||||
store legacy.LegacyIdentityStore
|
||||
}
|
||||
|
||||
// New implements rest.Storage.
|
||||
func (s *LegacyTokenRest) New() runtime.Object {
|
||||
return &iamv0.UserTeamList{}
|
||||
}
|
||||
|
||||
// Destroy implements rest.Storage.
|
||||
func (s *LegacyTokenRest) Destroy() {}
|
||||
|
||||
// NamespaceScoped implements rest.Scoper.
|
||||
func (s *LegacyTokenRest) NamespaceScoped() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
// ProducesMIMETypes implements rest.StorageMetadata.
|
||||
func (s *LegacyTokenRest) ProducesMIMETypes(verb string) []string {
|
||||
return []string{"application/json"}
|
||||
}
|
||||
|
||||
// ProducesObject implements rest.StorageMetadata.
|
||||
func (s *LegacyTokenRest) ProducesObject(verb string) interface{} {
|
||||
return s.New()
|
||||
}
|
||||
|
||||
// Connect implements rest.Connecter.
|
||||
func (s *LegacyTokenRest) Connect(ctx context.Context, name string, options runtime.Object, responder rest.Responder) (http.Handler, error) {
|
||||
ns, err := request.NamespaceInfoFrom(ctx, true)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
res, err := s.store.ListServiceAccountTokens(ctx, ns, legacy.ListServiceAccountTokenQuery{
|
||||
UID: name,
|
||||
Pagination: common.PaginationFromListQuery(r.URL.Query()),
|
||||
})
|
||||
if err != nil {
|
||||
responder.Error(err)
|
||||
return
|
||||
}
|
||||
|
||||
list := &iamv0.ServiceAccountTokenList{Items: make([]iamv0.ServiceAccountToken, 0, len(res.Items))}
|
||||
|
||||
for _, t := range res.Items {
|
||||
list.Items = append(list.Items, mapToToken(t))
|
||||
}
|
||||
|
||||
list.ListMeta.Continue = common.OptionalFormatInt(res.Continue)
|
||||
|
||||
responder.Object(http.StatusOK, list)
|
||||
}), nil
|
||||
}
|
||||
|
||||
// NewConnectOptions implements rest.Connecter.
|
||||
func (s *LegacyTokenRest) NewConnectOptions() (runtime.Object, bool, string) {
|
||||
return nil, false, ""
|
||||
}
|
||||
|
||||
// ConnectMethods implements rest.Connecter.
|
||||
func (s *LegacyTokenRest) ConnectMethods() []string {
|
||||
return []string{http.MethodGet}
|
||||
}
|
||||
|
||||
func mapToToken(t legacy.ServiceAccountToken) iamv0.ServiceAccountToken {
|
||||
var expires, lastUsed *metav1.Time
|
||||
|
||||
if t.Expires != nil {
|
||||
ts := metav1.NewTime(time.Unix(*t.Expires, 0))
|
||||
expires = &ts
|
||||
}
|
||||
|
||||
if t.LastUsed != nil {
|
||||
ts := metav1.NewTime(*t.LastUsed)
|
||||
lastUsed = &ts
|
||||
}
|
||||
|
||||
return iamv0.ServiceAccountToken{
|
||||
Name: t.Name,
|
||||
Expires: expires,
|
||||
LastUsed: lastUsed,
|
||||
Revoked: t.Revoked,
|
||||
Created: metav1.NewTime(t.Created),
|
||||
}
|
||||
}
|
||||
@@ -11,11 +11,10 @@ import (
|
||||
"k8s.io/apiserver/pkg/registry/rest"
|
||||
|
||||
"github.com/grafana/grafana/pkg/apimachinery/utils"
|
||||
identityv0 "github.com/grafana/grafana/pkg/apis/iam/v0alpha1"
|
||||
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/user"
|
||||
)
|
||||
|
||||
var (
|
||||
@@ -26,7 +25,7 @@ var (
|
||||
_ rest.Storage = (*LegacyStore)(nil)
|
||||
)
|
||||
|
||||
var resource = identityv0.ServiceAccountResourceInfo
|
||||
var resource = iamv0.ServiceAccountResourceInfo
|
||||
|
||||
func NewLegacyStore(store legacy.LegacyIdentityStore) *LegacyStore {
|
||||
return &LegacyStore{store}
|
||||
@@ -63,20 +62,18 @@ func (s *LegacyStore) List(ctx context.Context, options *internalversion.ListOpt
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
query := legacy.ListUserQuery{
|
||||
OrgID: ns.OrgID,
|
||||
IsServiceAccount: true,
|
||||
Pagination: common.PaginationFromListOptions(options),
|
||||
}
|
||||
|
||||
found, err := s.store.ListUsers(ctx, ns, query)
|
||||
found, err := s.store.ListServiceAccounts(ctx, ns, legacy.ListServiceAccountsQuery{
|
||||
OrgID: ns.OrgID,
|
||||
Pagination: common.PaginationFromListOptions(options),
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
list := &identityv0.ServiceAccountList{}
|
||||
for _, item := range found.Users {
|
||||
list.Items = append(list.Items, *toSAItem(&item, ns.Value))
|
||||
list := &iamv0.ServiceAccountList{}
|
||||
for _, item := range found.Items {
|
||||
list.Items = append(list.Items, toSAItem(item, ns.Value))
|
||||
}
|
||||
|
||||
list.ListMeta.Continue = common.OptionalFormatInt(found.Continue)
|
||||
@@ -85,26 +82,24 @@ func (s *LegacyStore) List(ctx context.Context, options *internalversion.ListOpt
|
||||
return list, err
|
||||
}
|
||||
|
||||
func toSAItem(u *user.User, ns string) *identityv0.ServiceAccount {
|
||||
item := &identityv0.ServiceAccount{
|
||||
func toSAItem(sa legacy.ServiceAccount, ns string) iamv0.ServiceAccount {
|
||||
item := iamv0.ServiceAccount{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: u.UID,
|
||||
Name: sa.UID,
|
||||
Namespace: ns,
|
||||
ResourceVersion: fmt.Sprintf("%d", u.Updated.UnixMilli()),
|
||||
CreationTimestamp: metav1.NewTime(u.Created),
|
||||
ResourceVersion: fmt.Sprintf("%d", sa.Updated.UnixMilli()),
|
||||
CreationTimestamp: metav1.NewTime(sa.Created),
|
||||
},
|
||||
Spec: identityv0.ServiceAccountSpec{
|
||||
Name: u.Name,
|
||||
Email: u.Email,
|
||||
EmailVerified: u.EmailVerified,
|
||||
Disabled: u.IsDisabled,
|
||||
Spec: iamv0.ServiceAccountSpec{
|
||||
Title: sa.Name,
|
||||
Disabled: sa.Disabled,
|
||||
},
|
||||
}
|
||||
obj, _ := utils.MetaAccessor(item)
|
||||
obj.SetUpdatedTimestamp(&u.Updated)
|
||||
obj, _ := utils.MetaAccessor(&item)
|
||||
obj.SetUpdatedTimestamp(&sa.Updated)
|
||||
obj.SetOriginInfo(&utils.ResourceOriginInfo{
|
||||
Name: "SQL",
|
||||
Path: strconv.FormatInt(u.ID, 10),
|
||||
Path: strconv.FormatInt(sa.ID, 10),
|
||||
})
|
||||
return item
|
||||
}
|
||||
@@ -114,18 +109,19 @@ func (s *LegacyStore) Get(ctx context.Context, name string, options *metav1.GetO
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
query := legacy.ListUserQuery{
|
||||
OrgID: ns.OrgID,
|
||||
IsServiceAccount: true,
|
||||
Pagination: common.Pagination{Limit: 1},
|
||||
}
|
||||
|
||||
found, err := s.store.ListUsers(ctx, ns, query)
|
||||
found, err := s.store.ListServiceAccounts(ctx, ns, legacy.ListServiceAccountsQuery{
|
||||
UID: name,
|
||||
OrgID: ns.OrgID,
|
||||
Pagination: common.Pagination{Limit: 1},
|
||||
})
|
||||
if found == nil || err != nil {
|
||||
return nil, resource.NewNotFound(name)
|
||||
}
|
||||
if len(found.Users) < 1 {
|
||||
if len(found.Items) < 1 {
|
||||
return nil, resource.NewNotFound(name)
|
||||
}
|
||||
return toSAItem(&found.Users[0], ns.Value), nil
|
||||
|
||||
res := toSAItem(found.Items[0], ns.Value)
|
||||
return &res, nil
|
||||
}
|
||||
|
||||
@@ -14,7 +14,7 @@ import (
|
||||
"k8s.io/apimachinery/pkg/types"
|
||||
"k8s.io/apiserver/pkg/registry/rest"
|
||||
|
||||
identityv0 "github.com/grafana/grafana/pkg/apis/iam/v0alpha1"
|
||||
iamv0 "github.com/grafana/grafana/pkg/apis/iam/v0alpha1"
|
||||
"github.com/grafana/grafana/pkg/services/apiserver/endpoints/request"
|
||||
"github.com/grafana/grafana/pkg/services/ssosettings"
|
||||
ssomodels "github.com/grafana/grafana/pkg/services/ssosettings/models"
|
||||
@@ -30,7 +30,7 @@ var (
|
||||
_ rest.GracefulDeleter = (*LegacyStore)(nil)
|
||||
)
|
||||
|
||||
var resource = identityv0.SSOSettingResourceInfo
|
||||
var resource = iamv0.SSOSettingResourceInfo
|
||||
|
||||
func NewLegacyStore(service ssosettings.Service) *LegacyStore {
|
||||
return &LegacyStore{service}
|
||||
@@ -78,7 +78,7 @@ func (s *LegacyStore) List(ctx context.Context, options *internalversion.ListOpt
|
||||
return nil, fmt.Errorf("failed to list sso settings: %w", err)
|
||||
}
|
||||
|
||||
list := &identityv0.SSOSettingList{}
|
||||
list := &iamv0.SSOSettingList{}
|
||||
for _, s := range settings {
|
||||
list.Items = append(list.Items, mapToObject(ns.Value, s))
|
||||
}
|
||||
@@ -128,7 +128,7 @@ func (s *LegacyStore) Update(
|
||||
return old, created, err
|
||||
}
|
||||
|
||||
setting, ok := obj.(*identityv0.SSOSetting)
|
||||
setting, ok := obj.(*iamv0.SSOSetting)
|
||||
if !ok {
|
||||
return old, created, errors.New("expected ssosetting after update")
|
||||
}
|
||||
@@ -153,7 +153,7 @@ func (s *LegacyStore) Delete(
|
||||
return obj, false, err
|
||||
}
|
||||
|
||||
old, ok := obj.(*identityv0.SSOSetting)
|
||||
old, ok := obj.(*iamv0.SSOSetting)
|
||||
if !ok {
|
||||
return obj, false, errors.New("expected ssosetting")
|
||||
}
|
||||
@@ -182,10 +182,10 @@ func (s *LegacyStore) Delete(
|
||||
return afterDelete, false, err
|
||||
}
|
||||
|
||||
func mapToObject(ns string, s *ssomodels.SSOSettings) identityv0.SSOSetting {
|
||||
source := identityv0.SourceDB
|
||||
func mapToObject(ns string, s *ssomodels.SSOSettings) iamv0.SSOSetting {
|
||||
source := iamv0.SourceDB
|
||||
if s.Source == ssomodels.System {
|
||||
source = identityv0.SourceSystem
|
||||
source = iamv0.SourceSystem
|
||||
}
|
||||
|
||||
version := "0"
|
||||
@@ -193,7 +193,7 @@ func mapToObject(ns string, s *ssomodels.SSOSettings) identityv0.SSOSetting {
|
||||
version = fmt.Sprintf("%d", s.Updated.UnixMilli())
|
||||
}
|
||||
|
||||
object := identityv0.SSOSetting{
|
||||
object := iamv0.SSOSetting{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: s.Provider,
|
||||
Namespace: ns,
|
||||
@@ -201,7 +201,7 @@ func mapToObject(ns string, s *ssomodels.SSOSettings) identityv0.SSOSetting {
|
||||
ResourceVersion: version,
|
||||
CreationTimestamp: metav1.NewTime(s.Updated),
|
||||
},
|
||||
Spec: identityv0.SSOSettingSpec{
|
||||
Spec: iamv0.SSOSettingSpec{
|
||||
Source: source,
|
||||
Settings: commonv1.Unstructured{Object: s.Settings},
|
||||
},
|
||||
@@ -210,7 +210,7 @@ func mapToObject(ns string, s *ssomodels.SSOSettings) identityv0.SSOSetting {
|
||||
return object
|
||||
}
|
||||
|
||||
func mapToModel(obj *identityv0.SSOSetting) *ssomodels.SSOSettings {
|
||||
func mapToModel(obj *iamv0.SSOSetting) *ssomodels.SSOSettings {
|
||||
return &ssomodels.SSOSettings{
|
||||
Provider: obj.Name,
|
||||
Settings: obj.Spec.Settings.Object,
|
||||
|
||||
@@ -9,7 +9,7 @@ import (
|
||||
|
||||
"github.com/grafana/authlib/claims"
|
||||
"github.com/grafana/grafana/pkg/api/dtos"
|
||||
identityv0 "github.com/grafana/grafana/pkg/apis/iam/v0alpha1"
|
||||
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"
|
||||
@@ -33,7 +33,7 @@ type LegacyTeamMemberREST struct {
|
||||
|
||||
// New implements rest.Storage.
|
||||
func (s *LegacyTeamMemberREST) New() runtime.Object {
|
||||
return &identityv0.TeamMemberList{}
|
||||
return &iamv0.TeamMemberList{}
|
||||
}
|
||||
|
||||
// Destroy implements rest.Storage.
|
||||
@@ -71,7 +71,7 @@ func (s *LegacyTeamMemberREST) Connect(ctx context.Context, name string, options
|
||||
return
|
||||
}
|
||||
|
||||
list := &identityv0.TeamMemberList{Items: make([]identityv0.TeamMember, 0, len(res.Members))}
|
||||
list := &iamv0.TeamMemberList{Items: make([]iamv0.TeamMember, 0, len(res.Members))}
|
||||
|
||||
for _, m := range res.Members {
|
||||
list.Items = append(list.Items, mapToTeamMember(m))
|
||||
@@ -95,9 +95,9 @@ func (s *LegacyTeamMemberREST) ConnectMethods() []string {
|
||||
|
||||
var cfg = &setting.Cfg{}
|
||||
|
||||
func mapToTeamMember(m legacy.TeamMember) identityv0.TeamMember {
|
||||
return identityv0.TeamMember{
|
||||
IdentityDisplay: identityv0.IdentityDisplay{
|
||||
func mapToTeamMember(m legacy.TeamMember) iamv0.TeamMember {
|
||||
return iamv0.TeamMember{
|
||||
IdentityDisplay: iamv0.IdentityDisplay{
|
||||
IdentityType: claims.TypeUser,
|
||||
UID: m.UserUID,
|
||||
Display: m.Name,
|
||||
|
||||
@@ -11,7 +11,7 @@ import (
|
||||
|
||||
"github.com/grafana/authlib/claims"
|
||||
"github.com/grafana/grafana/pkg/apimachinery/utils"
|
||||
identityv0 "github.com/grafana/grafana/pkg/apis/iam/v0alpha1"
|
||||
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"
|
||||
@@ -25,7 +25,7 @@ var (
|
||||
_ rest.Storage = (*LegacyStore)(nil)
|
||||
)
|
||||
|
||||
var resource = identityv0.TeamResourceInfo
|
||||
var resource = iamv0.TeamResourceInfo
|
||||
|
||||
func NewLegacyStore(store legacy.LegacyIdentityStore) *LegacyStore {
|
||||
return &LegacyStore{store}
|
||||
@@ -58,25 +58,25 @@ func (s *LegacyStore) ConvertToTable(ctx context.Context, object runtime.Object,
|
||||
return resource.TableConverter().ConvertToTable(ctx, object, tableOptions)
|
||||
}
|
||||
|
||||
func (s *LegacyStore) doList(ctx context.Context, ns claims.NamespaceInfo, query legacy.ListTeamQuery) (*identityv0.TeamList, error) {
|
||||
func (s *LegacyStore) doList(ctx context.Context, ns claims.NamespaceInfo, query legacy.ListTeamQuery) (*iamv0.TeamList, error) {
|
||||
rsp, err := s.store.ListTeams(ctx, ns, query)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
list := &identityv0.TeamList{
|
||||
list := &iamv0.TeamList{
|
||||
ListMeta: metav1.ListMeta{
|
||||
ResourceVersion: strconv.FormatInt(rsp.RV, 10),
|
||||
},
|
||||
}
|
||||
for _, team := range rsp.Teams {
|
||||
item := identityv0.Team{
|
||||
item := iamv0.Team{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: team.UID,
|
||||
Namespace: ns.Value,
|
||||
CreationTimestamp: metav1.NewTime(team.Created),
|
||||
ResourceVersion: strconv.FormatInt(team.Updated.UnixMilli(), 10),
|
||||
},
|
||||
Spec: identityv0.TeamSpec{
|
||||
Spec: iamv0.TeamSpec{
|
||||
Title: team.Name,
|
||||
Email: team.Email,
|
||||
},
|
||||
|
||||
@@ -11,14 +11,14 @@ import (
|
||||
"k8s.io/apiserver/pkg/registry/rest"
|
||||
|
||||
"github.com/grafana/authlib/claims"
|
||||
identityv0 "github.com/grafana/grafana/pkg/apis/iam/v0alpha1"
|
||||
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 = identityv0.TeamBindingResourceInfo
|
||||
var bindingResource = iamv0.TeamBindingResourceInfo
|
||||
|
||||
var (
|
||||
_ rest.Storage = (*LegacyBindingStore)(nil)
|
||||
@@ -102,8 +102,8 @@ func (l *LegacyBindingStore) List(ctx context.Context, options *internalversion.
|
||||
return nil, err
|
||||
}
|
||||
|
||||
list := identityv0.TeamBindingList{
|
||||
Items: make([]identityv0.TeamBinding, 0, len(res.Bindings)),
|
||||
list := iamv0.TeamBindingList{
|
||||
Items: make([]iamv0.TeamBinding, 0, len(res.Bindings)),
|
||||
}
|
||||
|
||||
for _, b := range res.Bindings {
|
||||
@@ -116,7 +116,7 @@ func (l *LegacyBindingStore) List(ctx context.Context, options *internalversion.
|
||||
return &list, nil
|
||||
}
|
||||
|
||||
func mapToBindingObject(ns claims.NamespaceInfo, b legacy.TeamBinding) identityv0.TeamBinding {
|
||||
func mapToBindingObject(ns claims.NamespaceInfo, b legacy.TeamBinding) iamv0.TeamBinding {
|
||||
rv := time.Time{}
|
||||
ct := time.Now()
|
||||
|
||||
@@ -129,15 +129,15 @@ func mapToBindingObject(ns claims.NamespaceInfo, b legacy.TeamBinding) identityv
|
||||
}
|
||||
}
|
||||
|
||||
return identityv0.TeamBinding{
|
||||
return iamv0.TeamBinding{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: b.TeamUID,
|
||||
Namespace: ns.Value,
|
||||
ResourceVersion: strconv.FormatInt(rv.UnixMilli(), 10),
|
||||
CreationTimestamp: metav1.NewTime(ct),
|
||||
},
|
||||
Spec: identityv0.TeamBindingSpec{
|
||||
TeamRef: identityv0.TeamRef{
|
||||
Spec: iamv0.TeamBindingSpec{
|
||||
TeamRef: iamv0.TeamRef{
|
||||
Name: b.TeamUID,
|
||||
},
|
||||
Subjects: mapToSubjects(b.Members),
|
||||
@@ -145,10 +145,10 @@ func mapToBindingObject(ns claims.NamespaceInfo, b legacy.TeamBinding) identityv
|
||||
}
|
||||
}
|
||||
|
||||
func mapToSubjects(members []legacy.TeamMember) []identityv0.TeamSubject {
|
||||
out := make([]identityv0.TeamSubject, 0, len(members))
|
||||
func mapToSubjects(members []legacy.TeamMember) []iamv0.TeamSubject {
|
||||
out := make([]iamv0.TeamSubject, 0, len(members))
|
||||
for _, m := range members {
|
||||
out = append(out, identityv0.TeamSubject{
|
||||
out = append(out, iamv0.TeamSubject{
|
||||
Name: m.MemberID(),
|
||||
Permission: common.MapTeamPermission(m.Permission),
|
||||
})
|
||||
@@ -156,10 +156,10 @@ func mapToSubjects(members []legacy.TeamMember) []identityv0.TeamSubject {
|
||||
return out
|
||||
}
|
||||
|
||||
func mapPermisson(p team.PermissionType) identityv0.TeamPermission {
|
||||
func mapPermisson(p team.PermissionType) iamv0.TeamPermission {
|
||||
if p == team.PermissionTypeAdmin {
|
||||
return identityv0.TeamPermissionAdmin
|
||||
return iamv0.TeamPermissionAdmin
|
||||
} else {
|
||||
return identityv0.TeamPermissionMember
|
||||
return iamv0.TeamPermissionMember
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,7 +8,7 @@ import (
|
||||
|
||||
"github.com/grafana/authlib/claims"
|
||||
"github.com/grafana/grafana/pkg/api/dtos"
|
||||
identity "github.com/grafana/grafana/pkg/apis/iam/v0alpha1"
|
||||
iamv0 "github.com/grafana/grafana/pkg/apis/iam/v0alpha1"
|
||||
"github.com/grafana/grafana/pkg/registry/apis/iam/legacy"
|
||||
"github.com/grafana/grafana/pkg/services/apiserver/endpoints/request"
|
||||
"github.com/grafana/grafana/pkg/setting"
|
||||
@@ -35,7 +35,7 @@ func NewLegacyDisplayREST(store legacy.LegacyIdentityStore) *LegacyDisplayREST {
|
||||
}
|
||||
|
||||
func (r *LegacyDisplayREST) New() runtime.Object {
|
||||
return &identity.IdentityDisplayResults{}
|
||||
return &iamv0.IdentityDisplayResults{}
|
||||
}
|
||||
|
||||
func (r *LegacyDisplayREST) Destroy() {}
|
||||
@@ -54,7 +54,7 @@ func (r *LegacyDisplayREST) ProducesMIMETypes(verb string) []string {
|
||||
}
|
||||
|
||||
func (r *LegacyDisplayREST) ProducesObject(verb string) any {
|
||||
return &identity.IdentityDisplayResults{}
|
||||
return &iamv0.IdentityDisplayResults{}
|
||||
}
|
||||
|
||||
func (r *LegacyDisplayREST) ConnectMethods() []string {
|
||||
@@ -91,13 +91,13 @@ func (r *LegacyDisplayREST) Connect(ctx context.Context, name string, _ runtime.
|
||||
return
|
||||
}
|
||||
|
||||
rsp := &identity.IdentityDisplayResults{
|
||||
rsp := &iamv0.IdentityDisplayResults{
|
||||
Keys: keys.keys,
|
||||
InvalidKeys: keys.invalid,
|
||||
Display: make([]identity.IdentityDisplay, 0, len(users.Users)+len(keys.disp)+1),
|
||||
Display: make([]iamv0.IdentityDisplay, 0, len(users.Users)+len(keys.disp)+1),
|
||||
}
|
||||
for _, user := range users.Users {
|
||||
disp := identity.IdentityDisplay{
|
||||
disp := iamv0.IdentityDisplay{
|
||||
IdentityType: claims.TypeUser,
|
||||
Display: user.NameOrFallback(),
|
||||
UID: user.UID,
|
||||
@@ -124,7 +124,7 @@ type dispKeys struct {
|
||||
invalid []string
|
||||
|
||||
// For terminal keys, this is a constant
|
||||
disp []identity.IdentityDisplay
|
||||
disp []iamv0.IdentityDisplay
|
||||
}
|
||||
|
||||
func parseKeys(req []string) dispKeys {
|
||||
@@ -145,14 +145,14 @@ func parseKeys(req []string) dispKeys {
|
||||
|
||||
switch t {
|
||||
case claims.TypeAnonymous:
|
||||
keys.disp = append(keys.disp, identity.IdentityDisplay{
|
||||
keys.disp = append(keys.disp, iamv0.IdentityDisplay{
|
||||
IdentityType: t,
|
||||
Display: "Anonymous",
|
||||
AvatarURL: dtos.GetGravatarUrl(fakeCfgForGravatar, string(t)),
|
||||
})
|
||||
continue
|
||||
case claims.TypeAPIKey:
|
||||
keys.disp = append(keys.disp, identity.IdentityDisplay{
|
||||
keys.disp = append(keys.disp, iamv0.IdentityDisplay{
|
||||
IdentityType: t,
|
||||
UID: key,
|
||||
Display: "API Key",
|
||||
@@ -160,7 +160,7 @@ func parseKeys(req []string) dispKeys {
|
||||
})
|
||||
continue
|
||||
case claims.TypeProvisioning:
|
||||
keys.disp = append(keys.disp, identity.IdentityDisplay{
|
||||
keys.disp = append(keys.disp, iamv0.IdentityDisplay{
|
||||
IdentityType: t,
|
||||
UID: "Provisioning",
|
||||
Display: "Provisioning",
|
||||
@@ -176,7 +176,7 @@ func parseKeys(req []string) dispKeys {
|
||||
id, err := strconv.ParseInt(key, 10, 64)
|
||||
if err == nil {
|
||||
if id == 0 {
|
||||
keys.disp = append(keys.disp, identity.IdentityDisplay{
|
||||
keys.disp = append(keys.disp, iamv0.IdentityDisplay{
|
||||
IdentityType: claims.TypeUser,
|
||||
UID: key,
|
||||
Display: "System admin",
|
||||
|
||||
@@ -7,7 +7,7 @@ import (
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/apiserver/pkg/registry/rest"
|
||||
|
||||
identityv0 "github.com/grafana/grafana/pkg/apis/iam/v0alpha1"
|
||||
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"
|
||||
@@ -30,7 +30,7 @@ type LegacyUserTeamREST struct {
|
||||
|
||||
// New implements rest.Storage.
|
||||
func (s *LegacyUserTeamREST) New() runtime.Object {
|
||||
return &identityv0.UserTeamList{}
|
||||
return &iamv0.UserTeamList{}
|
||||
}
|
||||
|
||||
// Destroy implements rest.Storage.
|
||||
@@ -68,7 +68,7 @@ func (s *LegacyUserTeamREST) Connect(ctx context.Context, name string, options r
|
||||
return
|
||||
}
|
||||
|
||||
list := &identityv0.UserTeamList{Items: make([]identityv0.UserTeam, 0, len(res.Items))}
|
||||
list := &iamv0.UserTeamList{Items: make([]iamv0.UserTeam, 0, len(res.Items))}
|
||||
|
||||
for _, m := range res.Items {
|
||||
list.Items = append(list.Items, mapToUserTeam(m))
|
||||
@@ -90,10 +90,10 @@ func (s *LegacyUserTeamREST) ConnectMethods() []string {
|
||||
return []string{http.MethodGet}
|
||||
}
|
||||
|
||||
func mapToUserTeam(t legacy.UserTeam) identityv0.UserTeam {
|
||||
return identityv0.UserTeam{
|
||||
func mapToUserTeam(t legacy.UserTeam) iamv0.UserTeam {
|
||||
return iamv0.UserTeam{
|
||||
Title: t.Name,
|
||||
TeamRef: identityv0.TeamRef{
|
||||
TeamRef: iamv0.TeamRef{
|
||||
Name: t.UID,
|
||||
},
|
||||
Permission: common.MapTeamPermission(t.Permission),
|
||||
|
||||
@@ -11,7 +11,7 @@ import (
|
||||
"k8s.io/apiserver/pkg/registry/rest"
|
||||
|
||||
"github.com/grafana/grafana/pkg/apimachinery/utils"
|
||||
identityv0 "github.com/grafana/grafana/pkg/apis/iam/v0alpha1"
|
||||
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"
|
||||
@@ -26,7 +26,7 @@ var (
|
||||
_ rest.Storage = (*LegacyStore)(nil)
|
||||
)
|
||||
|
||||
var resource = identityv0.UserResourceInfo
|
||||
var resource = iamv0.UserResourceInfo
|
||||
|
||||
func NewLegacyStore(store legacy.LegacyIdentityStore) *LegacyStore {
|
||||
return &LegacyStore{store}
|
||||
@@ -65,15 +65,14 @@ func (s *LegacyStore) List(ctx context.Context, options *internalversion.ListOpt
|
||||
}
|
||||
|
||||
found, err := s.store.ListUsers(ctx, ns, legacy.ListUserQuery{
|
||||
OrgID: ns.OrgID,
|
||||
IsServiceAccount: false,
|
||||
Pagination: common.PaginationFromListOptions(options),
|
||||
OrgID: ns.OrgID,
|
||||
Pagination: common.PaginationFromListOptions(options),
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
list := &identityv0.UserList{}
|
||||
list := &iamv0.UserList{}
|
||||
for _, item := range found.Users {
|
||||
list.Items = append(list.Items, *toUserItem(&item, ns.Value))
|
||||
}
|
||||
@@ -90,9 +89,8 @@ func (s *LegacyStore) Get(ctx context.Context, name string, options *metav1.GetO
|
||||
return nil, err
|
||||
}
|
||||
query := legacy.ListUserQuery{
|
||||
OrgID: ns.OrgID,
|
||||
IsServiceAccount: false,
|
||||
Pagination: common.Pagination{Limit: 1},
|
||||
OrgID: ns.OrgID,
|
||||
Pagination: common.Pagination{Limit: 1},
|
||||
}
|
||||
|
||||
found, err := s.store.ListUsers(ctx, ns, query)
|
||||
@@ -105,15 +103,15 @@ func (s *LegacyStore) Get(ctx context.Context, name string, options *metav1.GetO
|
||||
return toUserItem(&found.Users[0], ns.Value), nil
|
||||
}
|
||||
|
||||
func toUserItem(u *user.User, ns string) *identityv0.User {
|
||||
item := &identityv0.User{
|
||||
func toUserItem(u *user.User, ns string) *iamv0.User {
|
||||
item := &iamv0.User{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: u.UID,
|
||||
Namespace: ns,
|
||||
ResourceVersion: fmt.Sprintf("%d", u.Updated.UnixMilli()),
|
||||
CreationTimestamp: metav1.NewTime(u.Created),
|
||||
},
|
||||
Spec: identityv0.UserSpec{
|
||||
Spec: iamv0.UserSpec{
|
||||
Name: u.Name,
|
||||
Login: u.Login,
|
||||
Email: u.Email,
|
||||
|
||||
Reference in New Issue
Block a user