Folders: Build the same apiserver regardless of ST or MT (#111481)

This commit is contained in:
Ryan McKinley
2025-09-23 11:27:02 -05:00
committed by GitHub
parent f062e5a85f
commit a9de52c3e9
+39 -64
View File
@@ -47,22 +47,21 @@ var errNoResource = errors.New("resource name is required")
// This is used just so wire has something unique to return
type FolderAPIBuilder struct {
features featuremgmt.FeatureToggles
namespacer request.NamespaceMapper
features featuremgmt.FeatureToggles
namespacer request.NamespaceMapper
storage grafanarest.Storage
permissionStore reconcilers.PermissionStore
authorizer authorizer.Authorizer
accessClient authlib.AccessClient
parents parentsGetter
searcher resourcepb.ResourceIndexClient
permissionsOnCreate bool
// Legacy services -- these will not exist in the MT environment
folderSvc folder.LegacyService
folderPermissionsSvc accesscontrol.FolderPermissionsService
acService accesscontrol.Service
ac accesscontrol.AccessControl
storage grafanarest.Storage
permissionStore reconcilers.PermissionStore
accessClient authlib.AccessClient
authorizer authorizer.Authorizer
parents parentsGetter
searcher resourcepb.ResourceIndexClient
permissionsOnCreate bool
ignoreLegacy bool // skip legacy storage and only use unified storage
}
func RegisterAPIService(cfg *setting.Cfg,
@@ -99,10 +98,10 @@ func NewAPIService(ac authlib.AccessClient, searcher resource.ResourceClient, fe
features: features,
authorizer: newMultiTenantAuthorizer(ac),
searcher: searcher,
ignoreLegacy: true,
permissionStore: reconcilers.NewZanzanaPermissionStore(zanzanaClient),
}
}
func (b *FolderAPIBuilder) GetGroupVersion() schema.GroupVersion {
return resourceInfo.GroupVersion()
}
@@ -142,84 +141,60 @@ func (b *FolderAPIBuilder) AllowedV0Alpha1Resources() []string {
}
func (b *FolderAPIBuilder) UpdateAPIGroupInfo(apiGroupInfo *genericapiserver.APIGroupInfo, opts builder.APIGroupOptions) error {
scheme := opts.Scheme
optsGetter := opts.OptsGetter
dualWriteBuilder := opts.DualWriteBuilder
storage := map[string]rest.Storage{}
if b.ignoreLegacy {
opts.StorageOptsRegister(resourceInfo.GroupResource(), apistore.StorageOptions{
EnableFolderSupport: true,
RequireDeprecatedInternalID: true})
store, err := grafanaregistry.NewRegistryStore(opts.Scheme, resourceInfo, opts.OptsGetter)
if err != nil {
return err
}
b.registerPermissionHooks(store)
storage[resourceInfo.StoragePath()] = store
apiGroupInfo.VersionedResourcesStorageMap[folders.VERSION] = storage
b.storage = storage[resourceInfo.StoragePath()].(grafanarest.Storage)
b.parents = newParentsGetter(store, folder.MaxNestedFolderDepth)
return nil
}
legacyStore := &legacyStorage{
service: b.folderSvc,
namespacer: b.namespacer,
tableConverter: resourceInfo.TableConverter(),
}
opts.StorageOptsRegister(resourceInfo.GroupResource(), apistore.StorageOptions{
EnableFolderSupport: true,
RequireDeprecatedInternalID: true})
folderStore := &folderStorage{
tableConverter: resourceInfo.TableConverter(),
folderPermissionsSvc: b.folderPermissionsSvc,
acService: b.acService,
permissionsOnCreate: b.permissionsOnCreate,
unified, err := grafanaregistry.NewRegistryStore(opts.Scheme, resourceInfo, opts.OptsGetter)
if err != nil {
return err
}
b.registerPermissionHooks(unified)
b.storage = unified
if optsGetter != nil && dualWriteBuilder != nil {
store, err := grafanaregistry.NewRegistryStore(scheme, resourceInfo, optsGetter)
if b.folderSvc != nil {
legacyStore := &legacyStorage{
service: b.folderSvc,
namespacer: b.namespacer,
tableConverter: resourceInfo.TableConverter(),
}
dw, err := opts.DualWriteBuilder(resourceInfo.GroupResource(), legacyStore, unified)
if err != nil {
return err
}
b.registerPermissionHooks(store)
dw, err := dualWriteBuilder(resourceInfo.GroupResource(), legacyStore, store)
if err != nil {
return err
b.storage = &folderStorage{
tableConverter: resourceInfo.TableConverter(),
folderPermissionsSvc: b.folderPermissionsSvc,
acService: b.acService,
permissionsOnCreate: b.permissionsOnCreate,
store: dw,
}
folderStore.store = dw
}
storage[resourceInfo.StoragePath()] = folderStore
b.parents = newParentsGetter(folderStore, folder.MaxNestedFolderDepth) // used for validation
storage := map[string]rest.Storage{}
storage[resourceInfo.StoragePath()] = b.storage
b.parents = newParentsGetter(b.storage, folder.MaxNestedFolderDepth) // used for validation
storage[resourceInfo.StoragePath("parents")] = &subParentsREST{
getter: folderStore,
getter: b.storage,
parents: b.parents,
}
storage[resourceInfo.StoragePath("counts")] = &subCountREST{
getter: folderStore,
getter: b.storage,
searcher: b.searcher,
}
storage[resourceInfo.StoragePath("access")] = &subAccessREST{
getter: folderStore,
getter: b.storage,
accessClient: b.accessClient,
}
// Adds a path to return children of a given folder
storage[resourceInfo.StoragePath("children")] = &subChildrenREST{
getter: folderStore,
lister: storage[resourceInfo.StoragePath()].(rest.Lister),
getter: b.storage,
lister: b.storage,
}
apiGroupInfo.VersionedResourcesStorageMap[folders.VERSION] = storage
b.storage = storage[resourceInfo.StoragePath()].(grafanarest.Storage)
return nil
}