grafana-iam: Wire the roles api (#108577)

This commit is contained in:
Gabriel MABILLE
2025-07-28 13:36:27 +02:00
committed by GitHub
parent 1c15493635
commit 1a7a7f1d99
7 changed files with 54 additions and 6 deletions
+33 -1
View File
@@ -23,7 +23,8 @@ var CoreRoleInfo = utils.NewResourceInfo(GROUP, VERSION,
utils.TableColumns{
Definition: []metav1.TableColumnDefinition{
{Name: "Name", Type: "string", Format: "name"},
{Name: "Title", Type: "string", Format: "string", Description: "Core role name"}, // Not sure this is actually needed
{Name: "Group", Type: "string", Format: "group", Description: "Core role group"},
{Name: "Title", Type: "string", Format: "string", Description: "Core role name"},
{Name: "Created At", Type: "date"},
},
Reader: func(obj any) ([]interface{}, error) {
@@ -32,6 +33,7 @@ var CoreRoleInfo = utils.NewResourceInfo(GROUP, VERSION,
if core != nil {
return []interface{}{
core.Name,
core.Spec.Group,
core.Spec.Title,
core.CreationTimestamp.UTC().Format(time.RFC3339),
}, nil
@@ -42,6 +44,34 @@ var CoreRoleInfo = utils.NewResourceInfo(GROUP, VERSION,
},
)
var RoleInfo = utils.NewResourceInfo(GROUP, VERSION,
"roles", "role", "Role",
func() runtime.Object { return &Role{} },
func() runtime.Object { return &RoleList{} },
utils.TableColumns{
Definition: []metav1.TableColumnDefinition{
{Name: "Name", Type: "string", Format: "name"},
{Name: "Group", Type: "string", Format: "group", Description: "Role group"},
{Name: "Title", Type: "string", Format: "string", Description: "Role name"},
{Name: "Created At", Type: "date"},
},
Reader: func(obj any) ([]interface{}, error) {
role, ok := obj.(*Role)
if ok {
if role != nil {
return []interface{}{
role.Name,
role.Spec.Group,
role.Spec.Title,
role.CreationTimestamp.UTC().Format(time.RFC3339),
}, nil
}
}
return nil, fmt.Errorf("expected role")
},
},
)
var (
SchemeBuilder runtime.SchemeBuilder
localSchemeBuilder = &SchemeBuilder
@@ -58,6 +88,8 @@ func addKnownTypes(scheme *runtime.Scheme) error {
scheme.AddKnownTypes(schemeGroupVersion,
&CoreRole{},
&CoreRoleList{},
&Role{},
&RoleList{},
// What is this about?
&metav1.PartialObjectMetadata{},
+1
View File
@@ -32,6 +32,7 @@ func newIAMAuthorizer(accessClient authlib.AccessClient, legacyAccessClient auth
// Access specific resources
authorizer := gfauthorizer.NewResourceAuthorizer(accessClient)
resourceAuthorizer[iamv0.CoreRoleInfo.GetName()] = authorizer
resourceAuthorizer[iamv0.RoleInfo.GetName()] = authorizer
return &iamAuthorizer{resourceAuthorizer: resourceAuthorizer}
}
+6 -1
View File
@@ -17,14 +17,19 @@ var _ builder.APIGroupValidation = (*IdentityAccessManagementAPIBuilder)(nil)
var _ builder.APIGroupMutation = (*IdentityAccessManagementAPIBuilder)(nil)
// CoreRoleStorageBackend uses the resource.StorageBackend interface to provide storage for core roles.
// Used wire to identify the storage backend for core roles.
// Used by wire to identify the storage backend for core roles.
type CoreRoleStorageBackend interface{ resource.StorageBackend }
// RoleStorageBackend uses the resource.StorageBackend interface to provide storage for custom roles.
// Used by wire to identify the storage backend for custom roles.
type RoleStorageBackend interface{ resource.StorageBackend }
// This is used just so wire has something unique to return
type IdentityAccessManagementAPIBuilder struct {
// Stores
store legacy.LegacyIdentityStore
coreRolesStorage CoreRoleStorageBackend
rolesStorage RoleStorageBackend
// Access Control
authorizer authorizer.Authorizer
+10 -2
View File
@@ -50,6 +50,7 @@ func RegisterAPIService(
accessClient types.AccessClient,
reg prometheus.Registerer,
coreRolesStorage CoreRoleStorageBackend,
rolesStorage RoleStorageBackend,
) (*IdentityAccessManagementAPIBuilder, error) {
store := legacy.NewLegacySQLStores(legacysql.NewDatabaseProvider(sql))
legacyAccessClient := newLegacyAccessClient(ac, store)
@@ -58,6 +59,7 @@ func RegisterAPIService(
builder := &IdentityAccessManagementAPIBuilder{
store: store,
coreRolesStorage: coreRolesStorage,
rolesStorage: rolesStorage,
sso: ssoService,
authorizer: authorizer,
legacyAccessClient: legacyAccessClient,
@@ -157,11 +159,17 @@ func (b *IdentityAccessManagementAPIBuilder) UpdateAPIGroupInfo(apiGroupInfo *ge
if b.enableAuthZApis {
// v0alpha1
store, err := NewLocalStore(iamv0.CoreRoleInfo, apiGroupInfo.Scheme, opts.OptsGetter, b.reg, b.accessClient, b.coreRolesStorage)
coreRoleStore, err := NewLocalStore(iamv0.CoreRoleInfo, apiGroupInfo.Scheme, opts.OptsGetter, b.reg, b.accessClient, b.coreRolesStorage)
if err != nil {
return err
}
storage[iamv0.CoreRoleInfo.StoragePath()] = store
storage[iamv0.CoreRoleInfo.StoragePath()] = coreRoleStore
roleStore, err := NewLocalStore(iamv0.RoleInfo, apiGroupInfo.Scheme, opts.OptsGetter, b.reg, b.accessClient, b.rolesStorage)
if err != nil {
return err
}
storage[iamv0.RoleInfo.StoragePath()] = roleStore
}
apiGroupInfo.VersionedResourcesStorageMap[legacyiamv0.VERSION] = storage
+1
View File
@@ -24,6 +24,7 @@ import (
var WireSetExts = wire.NewSet(
noopstorage.ProvideStorageBackend,
wire.Bind(new(iam.CoreRoleStorageBackend), new(*noopstorage.StorageBackendImpl)),
wire.Bind(new(iam.RoleStorageBackend), new(*noopstorage.StorageBackendImpl)),
)
var WireSet = wire.NewSet(
+2 -2
View File
@@ -735,7 +735,7 @@ func Initialize(cfg *setting.Cfg, opts Options, apiOpts api.ServerOptions) (*Ser
}
folderAPIBuilder := folders.RegisterAPIService(cfg, featureToggles, apiserverService, folderimplService, folderPermissionsService, accessControl, acimplService, registerer, resourceClient)
storageBackendImpl := noopstorage.ProvideStorageBackend()
identityAccessManagementAPIBuilder, err := iam.RegisterAPIService(featureToggles, apiserverService, ssosettingsimplService, sqlStore, accessControl, accessClient, registerer, storageBackendImpl)
identityAccessManagementAPIBuilder, err := iam.RegisterAPIService(featureToggles, apiserverService, ssosettingsimplService, sqlStore, accessControl, accessClient, registerer, storageBackendImpl, storageBackendImpl)
if err != nil {
return nil, err
}
@@ -1293,7 +1293,7 @@ func InitializeForTest(t sqlutil.ITestDB, testingT interface {
}
folderAPIBuilder := folders.RegisterAPIService(cfg, featureToggles, apiserverService, folderimplService, folderPermissionsService, accessControl, acimplService, registerer, resourceClient)
storageBackendImpl := noopstorage.ProvideStorageBackend()
identityAccessManagementAPIBuilder, err := iam.RegisterAPIService(featureToggles, apiserverService, ssosettingsimplService, sqlStore, accessControl, accessClient, registerer, storageBackendImpl)
identityAccessManagementAPIBuilder, err := iam.RegisterAPIService(featureToggles, apiserverService, ssosettingsimplService, sqlStore, accessControl, accessClient, registerer, storageBackendImpl, storageBackendImpl)
if err != nil {
return nil, err
}
+1
View File
@@ -105,6 +105,7 @@ func NewMapperRegistry() MapperRegistry {
// Teams is a special case. We translate user permissions from id to uid based.
"teams": newResourceTranslation("teams", "uid", false),
"coreroles": newResourceTranslation("roles", "uid", false),
"roles": newResourceTranslation("roles", "uid", false),
},
"secret.grafana.app": {
"securevalues": newResourceTranslation("secret.securevalues", "uid", false),