K8s: handle multiple versions of the same group in standalone mode (#93199)

This commit is contained in:
Charandas
2024-09-23 19:07:52 -07:00
committed by GitHub
parent e699348d39
commit db97da3465
15 changed files with 91 additions and 164 deletions

View File

@ -4,10 +4,8 @@ import (
"context"
"fmt"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/apimachinery/pkg/runtime/serializer"
"k8s.io/apiserver/pkg/authorization/authorizer"
"k8s.io/apiserver/pkg/registry/generic"
"k8s.io/apiserver/pkg/registry/rest"
@ -72,29 +70,22 @@ func (t *NotificationsAPIBuilder) InstallSchema(scheme *runtime.Scheme) error {
return scheme.SetVersionPriority(notificationsModels.SchemeGroupVersion)
}
func (t *NotificationsAPIBuilder) GetAPIGroupInfo(
scheme *runtime.Scheme,
codecs serializer.CodecFactory,
optsGetter generic.RESTOptionsGetter,
dualWriteBuilder grafanarest.DualWriteBuilder,
) (*genericapiserver.APIGroupInfo, error) {
apiGroupInfo := genericapiserver.NewDefaultAPIGroupInfo(notificationsModels.GROUP, scheme, metav1.ParameterCodec, codecs)
func (t *NotificationsAPIBuilder) UpdateAPIGroupInfo(apiGroupInfo *genericapiserver.APIGroupInfo, scheme *runtime.Scheme, optsGetter generic.RESTOptionsGetter, dualWriteBuilder grafanarest.DualWriteBuilder) error {
intervals, err := timeInterval.NewStorage(t.ng.Api.MuteTimings, t.namespacer, scheme, optsGetter, dualWriteBuilder)
if err != nil {
return nil, fmt.Errorf("failed to initialize time-interval storage: %w", err)
return fmt.Errorf("failed to initialize time-interval storage: %w", err)
}
recvStorage, err := receiver.NewStorage(t.ng.Api.ReceiverService, t.namespacer, scheme, optsGetter, dualWriteBuilder, t.ng.Api.ReceiverService)
if err != nil {
return nil, fmt.Errorf("failed to initialize receiver storage: %w", err)
return fmt.Errorf("failed to initialize receiver storage: %w", err)
}
apiGroupInfo.VersionedResourcesStorageMap[notificationsModels.VERSION] = map[string]rest.Storage{
notificationsModels.TimeIntervalResourceInfo.StoragePath(): intervals,
notificationsModels.ReceiverResourceInfo.StoragePath(): recvStorage,
}
return &apiGroupInfo, nil
return nil
}
func (t *NotificationsAPIBuilder) GetOpenAPIDefinitions() common.GetOpenAPIDefinitions {

View File

@ -1,6 +1,16 @@
package dashboard
import (
"github.com/prometheus/client_golang/prometheus"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/apiserver/pkg/registry/generic"
"k8s.io/apiserver/pkg/registry/rest"
genericapiserver "k8s.io/apiserver/pkg/server"
"k8s.io/kube-openapi/pkg/common"
"k8s.io/kube-openapi/pkg/spec3"
dashboard "github.com/grafana/grafana/pkg/apis/dashboard/v0alpha1"
grafanaregistry "github.com/grafana/grafana/pkg/apiserver/registry/generic"
grafanarest "github.com/grafana/grafana/pkg/apiserver/rest"
@ -18,16 +28,6 @@ import (
"github.com/grafana/grafana/pkg/storage/legacysql"
"github.com/grafana/grafana/pkg/storage/unified/apistore"
"github.com/grafana/grafana/pkg/storage/unified/resource"
"github.com/prometheus/client_golang/prometheus"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/apimachinery/pkg/runtime/serializer"
"k8s.io/apiserver/pkg/registry/generic"
"k8s.io/apiserver/pkg/registry/rest"
genericapiserver "k8s.io/apiserver/pkg/server"
common "k8s.io/kube-openapi/pkg/common"
"k8s.io/kube-openapi/pkg/spec3"
)
var (
@ -124,18 +124,11 @@ func (b *DashboardsAPIBuilder) InstallSchema(scheme *runtime.Scheme) error {
return scheme.SetVersionPriority(resourceInfo.GroupVersion())
}
func (b *DashboardsAPIBuilder) GetAPIGroupInfo(
scheme *runtime.Scheme,
codecs serializer.CodecFactory, // pointer?
optsGetter generic.RESTOptionsGetter,
dualWriteBuilder grafanarest.DualWriteBuilder,
) (*genericapiserver.APIGroupInfo, error) {
apiGroupInfo := genericapiserver.NewDefaultAPIGroupInfo(dashboard.GROUP, scheme, metav1.ParameterCodec, codecs)
func (b *DashboardsAPIBuilder) UpdateAPIGroupInfo(apiGroupInfo *genericapiserver.APIGroupInfo, scheme *runtime.Scheme, optsGetter generic.RESTOptionsGetter, dualWriteBuilder grafanarest.DualWriteBuilder) error {
dash := b.legacy.resource
legacyStore, err := b.legacy.newStore(scheme, optsGetter)
if err != nil {
return nil, err
return err
}
storage := map[string]rest.Storage{}
@ -149,23 +142,23 @@ func (b *DashboardsAPIBuilder) GetAPIGroupInfo(
if optsGetter != nil && dualWriteBuilder != nil {
store, err := newStorage(scheme)
if err != nil {
return nil, err
return err
}
options := &generic.StoreOptions{RESTOptions: optsGetter, AttrFunc: grafanaregistry.GetAttrs}
if err := store.CompleteWithOptions(options); err != nil {
return nil, err
return err
}
storage[dash.StoragePath()], err = dualWriteBuilder(dash.GroupResource(), legacyStore, store)
if err != nil {
return nil, err
return err
}
}
// Register the DTO endpoint that will consolidate all dashboard bits
storage[dash.StoragePath("dto")], err = newDTOConnector(storage[dash.StoragePath()], b)
if err != nil {
return nil, err
return err
}
// Expose read only library panels
@ -174,7 +167,7 @@ func (b *DashboardsAPIBuilder) GetAPIGroupInfo(
}
apiGroupInfo.VersionedResourcesStorageMap[dashboard.VERSION] = storage
return &apiGroupInfo, nil
return nil
}
func (b *DashboardsAPIBuilder) GetOpenAPIDefinitions() common.GetOpenAPIDefinitions {

View File

@ -11,7 +11,6 @@ import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/apimachinery/pkg/runtime/serializer"
"k8s.io/apiserver/pkg/authorization/authorizer"
"k8s.io/apiserver/pkg/registry/generic"
"k8s.io/apiserver/pkg/registry/rest"
@ -120,13 +119,7 @@ func (b *SnapshotsAPIBuilder) InstallSchema(scheme *runtime.Scheme) error {
return scheme.SetVersionPriority(gv)
}
func (b *SnapshotsAPIBuilder) GetAPIGroupInfo(
scheme *runtime.Scheme,
codecs serializer.CodecFactory, // pointer?
optsGetter generic.RESTOptionsGetter,
_ grafanarest.DualWriteBuilder,
) (*genericapiserver.APIGroupInfo, error) {
apiGroupInfo := genericapiserver.NewDefaultAPIGroupInfo(dashboardsnapshot.GROUP, scheme, metav1.ParameterCodec, codecs)
func (b *SnapshotsAPIBuilder) UpdateAPIGroupInfo(apiGroupInfo *genericapiserver.APIGroupInfo, _ *runtime.Scheme, _ generic.RESTOptionsGetter, _ grafanarest.DualWriteBuilder) error {
storage := map[string]rest.Storage{}
legacyStore := &legacyStorage{
@ -147,7 +140,7 @@ func (b *SnapshotsAPIBuilder) GetAPIGroupInfo(
}
apiGroupInfo.VersionedResourcesStorageMap[dashboardsnapshot.VERSION] = storage
return &apiGroupInfo, nil
return nil
}
func (b *SnapshotsAPIBuilder) GetOpenAPIDefinitions() common.GetOpenAPIDefinitions {

View File

@ -24,7 +24,6 @@ import (
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/apimachinery/pkg/runtime/serializer"
"k8s.io/apiserver/pkg/registry/generic"
"k8s.io/apiserver/pkg/registry/rest"
genericapiserver "k8s.io/apiserver/pkg/server"
@ -200,12 +199,7 @@ func resourceFromPluginID(pluginID string) (utils.ResourceInfo, error) {
return datasource.GenericConnectionResourceInfo.WithGroupAndShortName(group, pluginID+"-connection"), nil
}
func (b *DataSourceAPIBuilder) GetAPIGroupInfo(
scheme *runtime.Scheme,
codecs serializer.CodecFactory, // pointer?
_ generic.RESTOptionsGetter,
_ grafanarest.DualWriteBuilder,
) (*genericapiserver.APIGroupInfo, error) {
func (b *DataSourceAPIBuilder) UpdateAPIGroupInfo(apiGroupInfo *genericapiserver.APIGroupInfo, _ *runtime.Scheme, _ generic.RESTOptionsGetter, _ grafanarest.DualWriteBuilder) error {
storage := map[string]rest.Storage{}
conn := b.connectionResourceInfo
@ -228,13 +222,8 @@ func (b *DataSourceAPIBuilder) GetAPIGroupInfo(
// Register hardcoded query schemas
err := queryschema.RegisterQueryTypes(b.queryTypes, storage)
// Create the group info
apiGroupInfo := genericapiserver.NewDefaultAPIGroupInfo(
conn.GroupResource().Group, scheme,
metav1.ParameterCodec, codecs)
apiGroupInfo.VersionedResourcesStorageMap[conn.GroupVersion().Version] = storage
return &apiGroupInfo, err
return err
}
func (b *DataSourceAPIBuilder) getPluginContext(ctx context.Context, uid string) (backend.PluginContext, error) {

View File

@ -4,7 +4,6 @@ import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/apimachinery/pkg/runtime/serializer"
"k8s.io/apiserver/pkg/authorization/authorizer"
"k8s.io/apiserver/pkg/registry/generic"
"k8s.io/apiserver/pkg/registry/rest"
@ -82,14 +81,7 @@ func (b *FeatureFlagAPIBuilder) InstallSchema(scheme *runtime.Scheme) error {
return scheme.SetVersionPriority(gv)
}
func (b *FeatureFlagAPIBuilder) GetAPIGroupInfo(
scheme *runtime.Scheme,
codecs serializer.CodecFactory, // pointer?
_ generic.RESTOptionsGetter,
_ grafanarest.DualWriteBuilder,
) (*genericapiserver.APIGroupInfo, error) {
apiGroupInfo := genericapiserver.NewDefaultAPIGroupInfo(v0alpha1.GROUP, scheme, metav1.ParameterCodec, codecs)
func (b *FeatureFlagAPIBuilder) UpdateAPIGroupInfo(apiGroupInfo *genericapiserver.APIGroupInfo, _ *runtime.Scheme, _ generic.RESTOptionsGetter, _ grafanarest.DualWriteBuilder) error {
featureStore := NewFeaturesStorage()
toggleStore := NewTogglesStorage(b.features)
@ -98,7 +90,7 @@ func (b *FeatureFlagAPIBuilder) GetAPIGroupInfo(
storage[toggleStore.resource.StoragePath()] = toggleStore
apiGroupInfo.VersionedResourcesStorageMap[v0alpha1.VERSION] = storage
return &apiGroupInfo, nil
return nil
}
func (b *FeatureFlagAPIBuilder) GetOpenAPIDefinitions() common.GetOpenAPIDefinitions {

View File

@ -7,7 +7,6 @@ import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/apimachinery/pkg/runtime/serializer"
"k8s.io/apiserver/pkg/authorization/authorizer"
"k8s.io/apiserver/pkg/registry/generic"
"k8s.io/apiserver/pkg/registry/rest"
@ -95,14 +94,7 @@ func (b *FolderAPIBuilder) InstallSchema(scheme *runtime.Scheme) error {
return scheme.SetVersionPriority(b.gv)
}
func (b *FolderAPIBuilder) GetAPIGroupInfo(
scheme *runtime.Scheme,
codecs serializer.CodecFactory, // pointer?
optsGetter generic.RESTOptionsGetter,
dualWriteBuilder grafanarest.DualWriteBuilder,
) (*genericapiserver.APIGroupInfo, error) {
apiGroupInfo := genericapiserver.NewDefaultAPIGroupInfo(v0alpha1.GROUP, scheme, metav1.ParameterCodec, codecs)
func (b *FolderAPIBuilder) UpdateAPIGroupInfo(apiGroupInfo *genericapiserver.APIGroupInfo, scheme *runtime.Scheme, optsGetter generic.RESTOptionsGetter, dualWriteBuilder grafanarest.DualWriteBuilder) error {
legacyStore := &legacyStorage{
service: b.folderSvc,
namespacer: b.namespacer,
@ -119,16 +111,16 @@ func (b *FolderAPIBuilder) GetAPIGroupInfo(
if optsGetter != nil && dualWriteBuilder != nil {
store, err := newStorage(scheme, optsGetter, legacyStore)
if err != nil {
return nil, err
return err
}
storage[resourceInfo.StoragePath()], err = dualWriteBuilder(resourceInfo.GroupResource(), legacyStore, store)
if err != nil {
return nil, err
return err
}
}
apiGroupInfo.VersionedResourcesStorageMap[v0alpha1.VERSION] = storage
return &apiGroupInfo, nil
return nil
}
func (b *FolderAPIBuilder) GetOpenAPIDefinitions() common.GetOpenAPIDefinitions {

View File

@ -6,7 +6,6 @@ import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/apimachinery/pkg/runtime/serializer"
"k8s.io/apiserver/pkg/authorization/authorizer"
"k8s.io/apiserver/pkg/registry/generic"
"k8s.io/apiserver/pkg/registry/rest"
@ -101,13 +100,7 @@ func (b *IdentityAccessManagementAPIBuilder) InstallSchema(scheme *runtime.Schem
return scheme.SetVersionPriority(iamv0.SchemeGroupVersion)
}
func (b *IdentityAccessManagementAPIBuilder) GetAPIGroupInfo(
scheme *runtime.Scheme,
codecs serializer.CodecFactory, // pointer?
optsGetter generic.RESTOptionsGetter,
dualWriteBuilder grafanarest.DualWriteBuilder,
) (*genericapiserver.APIGroupInfo, error) {
apiGroupInfo := genericapiserver.NewDefaultAPIGroupInfo(iamv0.GROUP, scheme, metav1.ParameterCodec, codecs)
func (b *IdentityAccessManagementAPIBuilder) UpdateAPIGroupInfo(apiGroupInfo *genericapiserver.APIGroupInfo, _ *runtime.Scheme, _ generic.RESTOptionsGetter, _ grafanarest.DualWriteBuilder) error {
storage := map[string]rest.Storage{}
teamResource := iamv0.TeamResourceInfo
@ -134,7 +127,7 @@ func (b *IdentityAccessManagementAPIBuilder) GetAPIGroupInfo(
storage["display"] = user.NewLegacyDisplayREST(b.store)
apiGroupInfo.VersionedResourcesStorageMap[iamv0.VERSION] = storage
return &apiGroupInfo, nil
return nil
}
func (b *IdentityAccessManagementAPIBuilder) GetOpenAPIDefinitions() common.GetOpenAPIDefinitions {

View File

@ -4,7 +4,6 @@ import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/apimachinery/pkg/runtime/serializer"
"k8s.io/apiserver/pkg/authorization/authorizer"
"k8s.io/apiserver/pkg/registry/generic"
"k8s.io/apiserver/pkg/registry/rest"
@ -66,19 +65,12 @@ func (b *PeakQAPIBuilder) InstallSchema(scheme *runtime.Scheme) error {
return scheme.SetVersionPriority(gv)
}
func (b *PeakQAPIBuilder) GetAPIGroupInfo(
scheme *runtime.Scheme,
codecs serializer.CodecFactory,
optsGetter generic.RESTOptionsGetter,
_ grafanarest.DualWriteBuilder,
) (*genericapiserver.APIGroupInfo, error) {
apiGroupInfo := genericapiserver.NewDefaultAPIGroupInfo(peakq.GROUP, scheme, metav1.ParameterCodec, codecs)
func (b *PeakQAPIBuilder) UpdateAPIGroupInfo(apiGroupInfo *genericapiserver.APIGroupInfo, scheme *runtime.Scheme, optsGetter generic.RESTOptionsGetter, _ grafanarest.DualWriteBuilder) error {
resourceInfo := peakq.QueryTemplateResourceInfo
storage := map[string]rest.Storage{}
peakqStorage, err := newStorage(scheme, optsGetter)
if err != nil {
return nil, err
return err
}
storage[resourceInfo.StoragePath()] = peakqStorage
storage[resourceInfo.StoragePath("render")] = &renderREST{
@ -86,7 +78,7 @@ func (b *PeakQAPIBuilder) GetAPIGroupInfo(
}
apiGroupInfo.VersionedResourcesStorageMap[peakq.VERSION] = storage
return &apiGroupInfo, nil
return nil
}
func (b *PeakQAPIBuilder) GetOpenAPIDefinitions() common.GetOpenAPIDefinitions {

View File

@ -7,12 +7,11 @@ import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/apimachinery/pkg/runtime/serializer"
"k8s.io/apiserver/pkg/authorization/authorizer"
"k8s.io/apiserver/pkg/registry/generic"
"k8s.io/apiserver/pkg/registry/rest"
genericapiserver "k8s.io/apiserver/pkg/server"
common "k8s.io/kube-openapi/pkg/common"
"k8s.io/kube-openapi/pkg/common"
playlist "github.com/grafana/grafana/apps/playlist/apis/playlist/v0alpha1"
"github.com/grafana/grafana/pkg/apimachinery/utils"
@ -79,13 +78,7 @@ func (b *PlaylistAPIBuilder) InstallSchema(scheme *runtime.Scheme) error {
return scheme.SetVersionPriority(b.gv)
}
func (b *PlaylistAPIBuilder) GetAPIGroupInfo(
scheme *runtime.Scheme,
codecs serializer.CodecFactory, // pointer?
optsGetter generic.RESTOptionsGetter,
dualWriteBuilder grafanarest.DualWriteBuilder,
) (*genericapiserver.APIGroupInfo, error) {
apiGroupInfo := genericapiserver.NewDefaultAPIGroupInfo(playlist.PlaylistKind().Group(), scheme, metav1.ParameterCodec, codecs)
func (b *PlaylistAPIBuilder) UpdateAPIGroupInfo(apiGroupInfo *genericapiserver.APIGroupInfo, scheme *runtime.Scheme, optsGetter generic.RESTOptionsGetter, dualWriteBuilder grafanarest.DualWriteBuilder) error {
storage := map[string]rest.Storage{}
gvr := schema.GroupVersionResource{
@ -127,17 +120,18 @@ func (b *PlaylistAPIBuilder) GetAPIGroupInfo(
if optsGetter != nil && dualWriteBuilder != nil {
store, err := newStorage(scheme, optsGetter, legacyStore)
if err != nil {
return nil, err
return err
}
dualWriter, err := dualWriteBuilder(gvr.GroupResource(), legacyStore, store)
if err != nil {
return nil, err
return err
}
storage[gvr.Resource] = dualWriter
}
apiGroupInfo.VersionedResourcesStorageMap[gvr.Version] = storage
return &apiGroupInfo, nil
return nil
}
func (b *PlaylistAPIBuilder) GetOpenAPIDefinitions() common.GetOpenAPIDefinitions {

View File

@ -7,7 +7,6 @@ import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/apimachinery/pkg/runtime/serializer"
"k8s.io/apiserver/pkg/authorization/authorizer"
"k8s.io/apiserver/pkg/registry/generic"
"k8s.io/apiserver/pkg/registry/rest"
@ -139,14 +138,8 @@ func (b *QueryAPIBuilder) InstallSchema(scheme *runtime.Scheme) error {
return scheme.SetVersionPriority(query.SchemeGroupVersion)
}
func (b *QueryAPIBuilder) GetAPIGroupInfo(
scheme *runtime.Scheme,
codecs serializer.CodecFactory, // pointer?
optsGetter generic.RESTOptionsGetter,
_ grafanarest.DualWriteBuilder,
) (*genericapiserver.APIGroupInfo, error) {
func (b *QueryAPIBuilder) UpdateAPIGroupInfo(apiGroupInfo *genericapiserver.APIGroupInfo, _ *runtime.Scheme, _ generic.RESTOptionsGetter, _ grafanarest.DualWriteBuilder) error {
gv := query.SchemeGroupVersion
apiGroupInfo := genericapiserver.NewDefaultAPIGroupInfo(gv.Group, scheme, metav1.ParameterCodec, codecs)
storage := map[string]rest.Storage{}
@ -166,7 +159,7 @@ func (b *QueryAPIBuilder) GetAPIGroupInfo(
err := queryschema.RegisterQueryTypes(b.queryTypes, storage)
apiGroupInfo.VersionedResourcesStorageMap[gv.Version] = storage
return &apiGroupInfo, err
return err
}
func (b *QueryAPIBuilder) GetOpenAPIDefinitions() common.GetOpenAPIDefinitions {

View File

@ -3,10 +3,8 @@ package scope
import (
"fmt"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/apimachinery/pkg/runtime/serializer"
"k8s.io/apiserver/pkg/authorization/authorizer"
"k8s.io/apiserver/pkg/registry/generic"
"k8s.io/apiserver/pkg/registry/rest"
@ -113,14 +111,7 @@ func (b *ScopeAPIBuilder) InstallSchema(scheme *runtime.Scheme) error {
return scheme.SetVersionPriority(scope.SchemeGroupVersion)
}
func (b *ScopeAPIBuilder) GetAPIGroupInfo(
scheme *runtime.Scheme,
codecs serializer.CodecFactory,
optsGetter generic.RESTOptionsGetter,
_ grafanarest.DualWriteBuilder,
) (*genericapiserver.APIGroupInfo, error) {
apiGroupInfo := genericapiserver.NewDefaultAPIGroupInfo(scope.GROUP, scheme, metav1.ParameterCodec, codecs)
func (b *ScopeAPIBuilder) UpdateAPIGroupInfo(apiGroupInfo *genericapiserver.APIGroupInfo, scheme *runtime.Scheme, optsGetter generic.RESTOptionsGetter, _ grafanarest.DualWriteBuilder) error {
scopeResourceInfo := scope.ScopeResourceInfo
scopeDashboardResourceInfo := scope.ScopeDashboardBindingResourceInfo
scopeNodeResourceInfo := scope.ScopeNodeResourceInfo
@ -129,20 +120,20 @@ func (b *ScopeAPIBuilder) GetAPIGroupInfo(
scopeStorage, err := newScopeStorage(scheme, optsGetter)
if err != nil {
return nil, err
return err
}
storage[scopeResourceInfo.StoragePath()] = scopeStorage
scopeDashboardStorage, scopedDashboardStatusStorage, err := newScopeDashboardBindingStorage(scheme, optsGetter)
if err != nil {
return nil, err
return err
}
storage[scopeDashboardResourceInfo.StoragePath()] = scopeDashboardStorage
storage[scopeDashboardResourceInfo.StoragePath()+"/status"] = scopedDashboardStatusStorage
scopeNodeStorage, err := newScopeNodeStorage(scheme, optsGetter)
if err != nil {
return nil, err
return err
}
storage[scopeNodeResourceInfo.StoragePath()] = scopeNodeStorage
@ -157,7 +148,7 @@ func (b *ScopeAPIBuilder) GetAPIGroupInfo(
storage["scope_dashboard_bindings"] = &findScopeDashboardsREST{scopeDashboardStorage: scopeDashboardStorage}
apiGroupInfo.VersionedResourcesStorageMap[scope.VERSION] = storage
return &apiGroupInfo, nil
return nil
}
func (b *ScopeAPIBuilder) GetOpenAPIDefinitions() common.GetOpenAPIDefinitions {

View File

@ -4,7 +4,6 @@ import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/apimachinery/pkg/runtime/serializer"
"k8s.io/apiserver/pkg/authorization/authorizer"
"k8s.io/apiserver/pkg/registry/generic"
"k8s.io/apiserver/pkg/registry/rest"
@ -71,23 +70,16 @@ func (b *ServiceAPIBuilder) InstallSchema(scheme *runtime.Scheme) error {
return scheme.SetVersionPriority(gv)
}
func (b *ServiceAPIBuilder) GetAPIGroupInfo(
scheme *runtime.Scheme,
codecs serializer.CodecFactory,
optsGetter generic.RESTOptionsGetter,
_ grafanarest.DualWriteBuilder,
) (*genericapiserver.APIGroupInfo, error) {
apiGroupInfo := genericapiserver.NewDefaultAPIGroupInfo(service.GROUP, scheme, metav1.ParameterCodec, codecs)
func (b *ServiceAPIBuilder) UpdateAPIGroupInfo(apiGroupInfo *genericapiserver.APIGroupInfo, scheme *runtime.Scheme, optsGetter generic.RESTOptionsGetter, _ grafanarest.DualWriteBuilder) error {
resourceInfo := service.ExternalNameResourceInfo
storage := map[string]rest.Storage{}
serviceStorage, err := newStorage(scheme, optsGetter)
if err != nil {
return nil, err
return err
}
storage[resourceInfo.StoragePath()] = serviceStorage
apiGroupInfo.VersionedResourcesStorageMap[service.VERSION] = storage
return &apiGroupInfo, nil
return nil
}
func (b *ServiceAPIBuilder) GetOpenAPIDefinitions() common.GetOpenAPIDefinitions {

View File

@ -284,19 +284,21 @@ func CreateAggregatorServer(config *Config, delegateAPIServer genericapiserver.D
return nil
})
serviceAPIGroupInfo := genericapiserver.NewDefaultAPIGroupInfo(servicev0alpha1.GROUP, aggregatorscheme.Scheme, metav1.ParameterCodec, aggregatorscheme.Codecs)
for _, b := range config.Builders {
serviceAPIGroupInfo, err := b.GetAPIGroupInfo(
err := b.UpdateAPIGroupInfo(
&serviceAPIGroupInfo,
aggregatorscheme.Scheme,
aggregatorscheme.Codecs,
aggregatorConfig.GenericConfig.RESTOptionsGetter,
nil, // no dual writer
)
if err != nil {
return nil, err
}
if err := aggregatorServer.GenericAPIServer.InstallAPIGroup(serviceAPIGroupInfo); err != nil {
return nil, err
}
}
if err := aggregatorServer.GenericAPIServer.InstallAPIGroup(&serviceAPIGroupInfo); err != nil {
return nil, err
}
return aggregatorServer, nil

View File

@ -5,7 +5,6 @@ import (
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/apimachinery/pkg/runtime/serializer"
"k8s.io/apiserver/pkg/authorization/authorizer"
"k8s.io/apiserver/pkg/registry/generic"
genericapiserver "k8s.io/apiserver/pkg/server"
@ -24,13 +23,19 @@ type APIGroupBuilder interface {
// Add the kinds to the server scheme
InstallSchema(scheme *runtime.Scheme) error
// Build the group+version behavior
GetAPIGroupInfo(
// UpdateAPIGroupInfo used to be a getter until we ran into the issue
// where separate API Group Info for the same group (different versions) aren't handled well by
// the InstallAPIGroup facility of genericapiserver. Also, we can only ever call InstallAPIGroup
// once on the genericapiserver per group, or we run into double registration startup errors.
//
// The caller should share the apiGroupInfo passed into this function across builder versions of the same group.
// UpdateAPIGroupInfo builds the group+version behavior updating the passed in apiGroupInfo in place
UpdateAPIGroupInfo(
apiGroupInfo *genericapiserver.APIGroupInfo,
scheme *runtime.Scheme,
codecs serializer.CodecFactory,
optsGetter generic.RESTOptionsGetter,
dualWrite grafanarest.DualWriteBuilder,
) (*genericapiserver.APIGroupInfo, error)
dualWriteBuilder grafanarest.DualWriteBuilder,
) error
// Get OpenAPI definitions
GetOpenAPIDefinitions() common.GetOpenAPIDefinitions

View File

@ -210,18 +210,33 @@ func InstallAPIs(
}
}
// NOTE: we build a map structure by version only for the purposes of InstallAPIGroup
// in other places, working with a flat []APIGroupBuilder list is much nicer
buildersGroupMap := make(map[string][]APIGroupBuilder, 0)
for _, b := range builders {
g, err := b.GetAPIGroupInfo(scheme, codecs, optsGetter, dualWrite)
if err != nil {
return err
group := b.GetGroupVersion().Group
if _, ok := buildersGroupMap[group]; !ok {
buildersGroupMap[group] = make([]APIGroupBuilder, 0)
}
if g == nil || len(g.PrioritizedVersions) < 1 {
continue
buildersGroupMap[group] = append(buildersGroupMap[group], b)
}
for group, buildersForGroup := range buildersGroupMap {
g := genericapiserver.NewDefaultAPIGroupInfo(group, scheme, metav1.ParameterCodec, codecs)
for _, b := range buildersForGroup {
if err := b.UpdateAPIGroupInfo(&g, scheme, optsGetter, dualWrite); err != nil {
return err
}
if len(g.PrioritizedVersions) < 1 {
continue
}
}
err = server.InstallAPIGroup(g)
err := server.InstallAPIGroup(&g)
if err != nil {
return err
}
}
return nil
}