K8s: Add APIGroupPostStartHookProvider (#97801)

This commit is contained in:
Todd Treece
2024-12-11 19:13:42 +02:00
committed by GitHub
parent 5d326b90ac
commit c5e8e71ee3
3 changed files with 141 additions and 0 deletions
+5
View File
@@ -62,6 +62,11 @@ type APIGroupRouteProvider interface {
GetAPIRoutes() *APIRoutes
}
type APIGroupPostStartHookProvider interface {
// GetPostStartHooks returns a list of functions that will be called after the server has started
GetPostStartHooks() (map[string]genericapiserver.PostStartHookFunc, error)
}
type APIGroupOptions struct {
Scheme *runtime.Scheme
OptsGetter generic.RESTOptionsGetter
+27
View File
@@ -141,6 +141,10 @@ func SetupConfig(
serverConfig.EffectiveVersion = utilversion.DefaultKubeEffectiveVersion()
if err := AddPostStartHooks(serverConfig, builders); err != nil {
return err
}
return nil
}
@@ -261,3 +265,26 @@ func InstallAPIs(
return nil
}
// AddPostStartHooks adds post start hooks to a generic API server config
func AddPostStartHooks(
config *genericapiserver.RecommendedConfig,
builders []APIGroupBuilder,
) error {
for _, b := range builders {
hookProvider, ok := b.(APIGroupPostStartHookProvider)
if !ok {
continue
}
hooks, err := hookProvider.GetPostStartHooks()
if err != nil {
return err
}
for name, hook := range hooks {
if err := config.AddPostStartHook(name, hook); err != nil {
return err
}
}
}
return nil
}
@@ -0,0 +1,109 @@
package builder_test
import (
"errors"
"testing"
"github.com/stretchr/testify/require"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/apiserver/pkg/authorization/authorizer"
"k8s.io/apiserver/pkg/server"
"k8s.io/kube-openapi/pkg/common"
"github.com/grafana/grafana/pkg/services/apiserver"
"github.com/grafana/grafana/pkg/services/apiserver/builder"
)
func TestAddPostStartHooks(t *testing.T) {
tests := []struct {
name string
builders []builder.APIGroupBuilder
wantErr bool
wantHooks []string
}{
{
name: "no builders",
builders: []builder.APIGroupBuilder{},
wantErr: false,
},
{
name: "builder without post start hooks",
builders: []builder.APIGroupBuilder{
&mockAPIGroupPostStartHookProvider{},
},
wantErr: false,
},
{
name: "builder with post start hooks",
builders: []builder.APIGroupBuilder{
&mockAPIGroupPostStartHookProvider{
hooks: map[string]server.PostStartHookFunc{
"test-hook": func(server.PostStartHookContext) error { return nil },
},
},
},
wantErr: false,
wantHooks: []string{"test-hook"},
},
{
name: "builder with post start hook provider error",
builders: []builder.APIGroupBuilder{
&mockAPIGroupPostStartHookProvider{
hooks: map[string]server.PostStartHookFunc{},
err: errors.New("hook provider error"),
},
},
wantErr: true,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
config := server.NewRecommendedConfig(apiserver.Codecs)
err := builder.AddPostStartHooks(config, tt.builders)
if tt.wantErr {
require.Error(t, err)
}
if len(tt.wantHooks) > 0 {
for _, hookName := range tt.wantHooks {
_, ok := config.PostStartHooks[hookName]
require.True(t, ok)
}
}
})
}
}
var _ builder.APIGroupBuilder = &mockAPIGroupPostStartHookProvider{}
var _ builder.APIGroupPostStartHookProvider = &mockAPIGroupPostStartHookProvider{}
type mockAPIGroupPostStartHookProvider struct {
hooks map[string]server.PostStartHookFunc
err error
}
func (m *mockAPIGroupPostStartHookProvider) GetPostStartHooks() (map[string]server.PostStartHookFunc, error) {
return m.hooks, m.err
}
func (m *mockAPIGroupPostStartHookProvider) GetGroupVersion() schema.GroupVersion {
return schema.GroupVersion{}
}
func (m *mockAPIGroupPostStartHookProvider) InstallSchema(scheme *runtime.Scheme) error {
return nil
}
func (m *mockAPIGroupPostStartHookProvider) UpdateAPIGroupInfo(apiGroupInfo *server.APIGroupInfo, opts builder.APIGroupOptions) error {
return nil
}
func (m *mockAPIGroupPostStartHookProvider) GetOpenAPIDefinitions() common.GetOpenAPIDefinitions {
return nil
}
func (m *mockAPIGroupPostStartHookProvider) GetAuthorizer() authorizer.Authorizer {
return nil
}