K8s: Make v0alpha1 opt-in (#107056)

This commit is contained in:
Stephanie Hingtgen
2025-06-20 16:37:17 -05:00
committed by GitHub
parent 0e35c8bdb4
commit ef6e28b955
21 changed files with 117 additions and 541 deletions
+7
View File
@@ -37,8 +37,15 @@ type APIGroupBuilder interface {
// Get OpenAPI definitions
GetOpenAPIDefinitions() common.GetOpenAPIDefinitions
// Do not return anything unless you have special circumstances! This is a list of resources that are allowed to be accessed in v0alpha1, with AllResourcesAllowed allowing all in the group.
// This is to prevent accidental exposure of experimental APIs. While developing, use the feature flag `grafanaAPIServerWithExperimentalAPIs`.
// And then, when you're ready to expose this to the end user, go to v1beta1 instead.
AllowedV0Alpha1Resources() []string
}
const AllResourcesAllowed = "*"
type APIGroupVersionProvider interface {
GetGroupVersion() schema.GroupVersion
}
+34
View File
@@ -32,6 +32,7 @@ import (
grafanarest "github.com/grafana/grafana/pkg/apiserver/rest"
"github.com/grafana/grafana/pkg/services/apiserver/endpoints/request"
"github.com/grafana/grafana/pkg/services/apiserver/options"
"github.com/grafana/grafana/pkg/services/featuremgmt"
"github.com/grafana/grafana/pkg/storage/legacysql/dualwrite"
"github.com/grafana/grafana/pkg/storage/unified/apistore"
)
@@ -276,6 +277,7 @@ func InstallAPIs(
serverLock ServerLockService,
dualWriteService dualwrite.Service,
optsregister apistore.StorageOptionsRegister,
features featuremgmt.FeatureToggles,
) error {
// dual writing is only enabled when the storage type is not legacy.
// this is needed to support setting a default RESTOptionsGetter for new APIs that don't
@@ -400,6 +402,25 @@ func InstallAPIs(
if len(g.PrioritizedVersions) < 1 {
continue
}
// if grafanaAPIServerWithExperimentalAPIs is not enabled, remove v0alpha1 resources unless explicitly allowed
if !features.IsEnabledGlobally(featuremgmt.FlagGrafanaAPIServerWithExperimentalAPIs) {
if resources, ok := g.VersionedResourcesStorageMap["v0alpha1"]; ok {
for name := range resources {
if !allowRegisteringResourceByInfo(b.AllowedV0Alpha1Resources(), name) {
delete(resources, name)
}
}
if len(resources) == 0 {
delete(g.VersionedResourcesStorageMap, "v0alpha1")
}
}
}
}
// skip installing the group if there are no resources left after filtering
if len(g.VersionedResourcesStorageMap) == 0 {
continue
}
err := server.InstallAPIGroup(&g)
@@ -433,3 +454,16 @@ func AddPostStartHooks(
}
return nil
}
func allowRegisteringResourceByInfo(allowedResources []string, name string) bool {
// trim any subresources from the name
name = strings.Split(name, "/")[0]
for _, allowedResource := range allowedResources {
if allowedResource == name || allowedResource == AllResourcesAllowed {
return true
}
}
return false
}
@@ -99,6 +99,10 @@ func (m *mockAPIGroupPostStartHookProvider) InstallSchema(scheme *runtime.Scheme
return nil
}
func (m *mockAPIGroupPostStartHookProvider) AllowedV0Alpha1Resources() []string {
return nil
}
func (m *mockAPIGroupPostStartHookProvider) UpdateAPIGroupInfo(apiGroupInfo *server.APIGroupInfo, opts builder.APIGroupOptions) error {
return nil
}
@@ -29,6 +29,10 @@ type AppBuilderConfig struct {
OpenAPIDefGetter common.GetOpenAPIDefinitions
ManagedKinds map[schema.GroupVersion][]resource.Kind
CustomConfig any
// Do not set anything here unless you have special circumstances! This is a list of resources that are allowed to be accessed in v0alpha1,
// to prevent accidental exposure of experimental APIs. While developing, use the feature flag `grafanaAPIServerWithExperimentalAPIs`.
// And then, when you're ready to expose this to the end user, go to v1beta1 instead.
AllowedV0Alpha1Resources []string
groupVersion schema.GroupVersion
}
@@ -109,6 +113,11 @@ func (b *appBuilder) InstallSchema(scheme *runtime.Scheme) error {
return scheme.SetVersionPriority(gv)
}
// AllowedV0Alpha1Resources returns the list of resources that are allowed to be accessed in v0alpha1
func (b *appBuilder) AllowedV0Alpha1Resources() []string {
return b.config.AllowedV0Alpha1Resources
}
// UpdateAPIGroupInfo implements APIGroupBuilder.UpdateAPIGroupInfo
func (b *appBuilder) UpdateAPIGroupInfo(apiGroupInfo *genericapiserver.APIGroupInfo, opts builder.APIGroupOptions) error {
for _, kinds := range b.config.ManagedKinds {
+1
View File
@@ -331,6 +331,7 @@ func (s *service) start(ctx context.Context) error {
s.serverLockService,
s.storageStatus,
optsregister,
s.features,
)
if err != nil {
return err