grafana-iam: Split UpdateAPIGroupInfo in multiple resource specific functions. (#116037)

* OnGoing fixing cyclomatic complexity

* Reduce cyclo complexity

* Spaces
This commit is contained in:
Gabriel MABILLE
2026-01-08 21:50:44 +01:00
committed by GitHub
parent f669bc4448
commit e95f8bf843
2 changed files with 113 additions and 55 deletions
@@ -179,19 +179,17 @@ func (r *ResourcePermissionsAuthorizer) FilterList(ctx context.Context, list run
canViewFuncs = map[schema.GroupResource]types.ItemChecker{}
)
for _, item := range l.Items {
gr := schema.GroupResource{
Group: item.Spec.Resource.ApiGroup,
Resource: item.Spec.Resource.Resource,
}
target := item.Spec.Resource
targetGR := schema.GroupResource{Group: target.ApiGroup, Resource: target.Resource}
// Reuse the same canView for items with the same resource
canView, found := canViewFuncs[gr]
canView, found := canViewFuncs[targetGR]
if !found {
listReq := types.ListRequest{
Namespace: item.Namespace,
Group: item.Spec.Resource.ApiGroup,
Resource: item.Spec.Resource.Resource,
Group: target.ApiGroup,
Resource: target.Resource,
Verb: utils.VerbGetPermissions,
}
@@ -200,12 +198,9 @@ func (r *ResourcePermissionsAuthorizer) FilterList(ctx context.Context, list run
return nil, err
}
canViewFuncs[gr] = canView
canViewFuncs[targetGR] = canView
}
target := item.Spec.Resource
targetGR := schema.GroupResource{Group: target.ApiGroup, Resource: target.Resource}
parent := ""
// Fetch the parent of the resource
// It's not efficient to do for every item in the list, but it's a good starting point.
+107 -44
View File
@@ -246,6 +246,8 @@ func (b *IdentityAccessManagementAPIBuilder) UpdateAPIGroupInfo(apiGroupInfo *ge
//nolint:staticcheck // not yet migrated to OpenFeature
enableZanzanaSync := b.features.IsEnabledGlobally(featuremgmt.FlagKubernetesAuthzZanzanaSync)
//nolint:staticcheck // not yet migrated to OpenFeature
enableAuthzApis := b.features.IsEnabledGlobally(featuremgmt.FlagKubernetesAuthzApis)
// teams + users must have shorter names because they are often used as part of another name
opts.StorageOptsRegister(iamv0.TeamResourceInfo.GroupResource(), apistore.StorageOptions{
@@ -255,6 +257,60 @@ func (b *IdentityAccessManagementAPIBuilder) UpdateAPIGroupInfo(apiGroupInfo *ge
MaximumNameLength: 80,
})
if err := b.UpdateTeamsAPIGroup(opts, storage); err != nil {
return err
}
if err := b.UpdateTeamBindingsAPIGroup(opts, storage, enableZanzanaSync); err != nil {
return err
}
if err := b.UpdateUsersAPIGroup(opts, storage, enableZanzanaSync); err != nil {
return err
}
if err := b.UpdateServiceAccountsAPIGroup(opts, storage); err != nil {
return err
}
// SSO settings apis
if b.ssoLegacyStore != nil {
ssoResource := legacyiamv0.SSOSettingResourceInfo
storage[ssoResource.StoragePath()] = b.ssoLegacyStore
}
if err := b.UpdateExternalGroupMappingAPIGroup(apiGroupInfo, opts, storage); err != nil {
return err
}
if enableAuthzApis {
// v0alpha1
if err := b.UpdateCoreRolesAPIGroup(apiGroupInfo, opts, storage, enableZanzanaSync); err != nil {
return err
}
// Role registration is delegated to the RoleApiInstaller
if err := b.roleApiInstaller.RegisterStorage(apiGroupInfo, &opts, storage); err != nil {
return err
}
if err := b.UpdateRoleBindingsAPIGroup(apiGroupInfo, opts, storage, enableZanzanaSync); err != nil {
return err
}
}
//nolint:staticcheck // not yet migrated to OpenFeature
if b.features.IsEnabledGlobally(featuremgmt.FlagKubernetesAuthzResourcePermissionApis) {
if err := b.UpdateResourcePermissionsAPIGroup(apiGroupInfo, opts, storage, enableZanzanaSync); err != nil {
return err
}
}
apiGroupInfo.VersionedResourcesStorageMap[legacyiamv0.VERSION] = storage
return nil
}
func (b *IdentityAccessManagementAPIBuilder) UpdateTeamsAPIGroup(opts builder.APIGroupOptions, storage map[string]rest.Storage) error {
teamResource := iamv0.TeamResourceInfo
teamUniStore, err := grafanaregistry.NewRegistryStore(opts.Scheme, teamResource, opts.OptsGetter)
if err != nil {
@@ -276,6 +332,10 @@ func (b *IdentityAccessManagementAPIBuilder) UpdateAPIGroupInfo(apiGroupInfo *ge
storage[teamResource.StoragePath("groups")] = b.teamGroupsHandler
}
return nil
}
func (b *IdentityAccessManagementAPIBuilder) UpdateTeamBindingsAPIGroup(opts builder.APIGroupOptions, storage map[string]rest.Storage, enableZanzanaSync bool) error {
teamBindingResource := iamv0.TeamBindingResourceInfo
teamBindingUniStore, err := grafanaregistry.NewRegistryStore(opts.Scheme, teamBindingResource, opts.OptsGetter)
if err != nil {
@@ -298,8 +358,10 @@ func (b *IdentityAccessManagementAPIBuilder) UpdateAPIGroupInfo(apiGroupInfo *ge
}
storage[teamBindingResource.StoragePath()] = dw
}
return nil
}
// User store registration
func (b *IdentityAccessManagementAPIBuilder) UpdateUsersAPIGroup(opts builder.APIGroupOptions, storage map[string]rest.Storage, enableZanzanaSync bool) error {
userResource := iamv0.UserResourceInfo
userUniStore, err := grafanaregistry.NewRegistryStore(opts.Scheme, userResource, opts.OptsGetter)
if err != nil {
@@ -325,7 +387,10 @@ func (b *IdentityAccessManagementAPIBuilder) UpdateAPIGroupInfo(apiGroupInfo *ge
storage[userResource.StoragePath("teams")] = user.NewLegacyTeamMemberREST(b.store)
// Service Accounts store registration
return nil
}
func (b *IdentityAccessManagementAPIBuilder) UpdateServiceAccountsAPIGroup(opts builder.APIGroupOptions, storage map[string]rest.Storage) error {
saResource := iamv0.ServiceAccountResourceInfo
saUniStore, err := grafanaregistry.NewRegistryStore(opts.Scheme, saResource, opts.OptsGetter)
if err != nil {
@@ -343,11 +408,10 @@ func (b *IdentityAccessManagementAPIBuilder) UpdateAPIGroupInfo(apiGroupInfo *ge
storage[saResource.StoragePath("tokens")] = serviceaccount.NewLegacyTokenREST(b.store)
if b.ssoLegacyStore != nil {
ssoResource := legacyiamv0.SSOSettingResourceInfo
storage[ssoResource.StoragePath()] = b.ssoLegacyStore
}
return nil
}
func (b *IdentityAccessManagementAPIBuilder) UpdateExternalGroupMappingAPIGroup(apiGroupInfo *genericapiserver.APIGroupInfo, opts builder.APIGroupOptions, storage map[string]rest.Storage) error {
extGroupMappingResource := iamv0.ExternalGroupMappingResourceInfo
extGroupMappingUniStore, err := grafanaregistry.NewRegistryStore(opts.Scheme, extGroupMappingResource, opts.OptsGetter)
if err != nil {
@@ -376,48 +440,47 @@ func (b *IdentityAccessManagementAPIBuilder) UpdateAPIGroupInfo(apiGroupInfo *ge
authzWrapper := storewrapper.New(extGroupMappingStore, iamauthorizer.NewExternalGroupMappingAuthorizer(b.accessClient))
storage[extGroupMappingResource.StoragePath()] = authzWrapper
return nil
}
//nolint:staticcheck // not yet migrated to OpenFeature
if b.features.IsEnabledGlobally(featuremgmt.FlagKubernetesAuthzApis) {
// v0alpha1
coreRoleStore, err := NewLocalStore(iamv0.CoreRoleInfo, apiGroupInfo.Scheme, opts.OptsGetter, b.reg, b.accessClient, b.coreRolesStorage)
if err != nil {
return err
}
if enableZanzanaSync {
b.logger.Info("Enabling hooks for CoreRole to sync to Zanzana")
h := NewRoleHooks(b.zClient, b.zTickets, b.logger)
coreRoleStore.AfterCreate = h.AfterRoleCreate
coreRoleStore.AfterDelete = h.AfterRoleDelete
coreRoleStore.BeginUpdate = h.BeginRoleUpdate
}
storage[iamv0.CoreRoleInfo.StoragePath()] = coreRoleStore
// Role registration is delegated to the RoleApiInstaller
if err := b.roleApiInstaller.RegisterStorage(apiGroupInfo, &opts, storage); err != nil {
return err
}
roleBindingStore, err := NewLocalStore(iamv0.RoleBindingInfo, apiGroupInfo.Scheme, opts.OptsGetter, b.reg, b.accessClient, b.roleBindingsStorage)
if err != nil {
return err
}
if enableZanzanaSync {
b.logger.Info("Enabling hooks for RoleBinding to sync to Zanzana")
roleBindingStore.AfterCreate = b.AfterRoleBindingCreate
roleBindingStore.AfterDelete = b.AfterRoleBindingDelete
roleBindingStore.BeginUpdate = b.BeginRoleBindingUpdate
}
storage[iamv0.RoleBindingInfo.StoragePath()] = roleBindingStore
func (b *IdentityAccessManagementAPIBuilder) UpdateCoreRolesAPIGroup(
apiGroupInfo *genericapiserver.APIGroupInfo,
opts builder.APIGroupOptions,
storage map[string]rest.Storage,
enableZanzanaSync bool,
) error {
coreRoleStore, err := NewLocalStore(iamv0.CoreRoleInfo, apiGroupInfo.Scheme, opts.OptsGetter, b.reg, b.accessClient, b.coreRolesStorage)
if err != nil {
return err
}
//nolint:staticcheck // not yet migrated to OpenFeature
if b.features.IsEnabledGlobally(featuremgmt.FlagKubernetesAuthzResourcePermissionApis) {
if err := b.UpdateResourcePermissionsAPIGroup(apiGroupInfo, opts, storage, enableZanzanaSync); err != nil {
return err
}
if enableZanzanaSync {
b.logger.Info("Enabling hooks for CoreRole to sync to Zanzana")
h := NewRoleHooks(b.zClient, b.zTickets, b.logger)
coreRoleStore.AfterCreate = h.AfterRoleCreate
coreRoleStore.AfterDelete = h.AfterRoleDelete
coreRoleStore.BeginUpdate = h.BeginRoleUpdate
}
storage[iamv0.CoreRoleInfo.StoragePath()] = coreRoleStore
return nil
}
apiGroupInfo.VersionedResourcesStorageMap[legacyiamv0.VERSION] = storage
func (b *IdentityAccessManagementAPIBuilder) UpdateRoleBindingsAPIGroup(
apiGroupInfo *genericapiserver.APIGroupInfo,
opts builder.APIGroupOptions,
storage map[string]rest.Storage,
enableZanzanaSync bool,
) error {
roleBindingStore, err := NewLocalStore(iamv0.RoleBindingInfo, apiGroupInfo.Scheme, opts.OptsGetter, b.reg, b.accessClient, b.roleBindingsStorage)
if err != nil {
return err
}
if enableZanzanaSync {
b.logger.Info("Enabling hooks for RoleBinding to sync to Zanzana")
roleBindingStore.AfterCreate = b.AfterRoleBindingCreate
roleBindingStore.AfterDelete = b.AfterRoleBindingDelete
roleBindingStore.BeginUpdate = b.BeginRoleBindingUpdate
}
storage[iamv0.RoleBindingInfo.StoragePath()] = roleBindingStore
return nil
}