Add GetResourceMapper to admission ObjectInterfaces

Kubernetes-commit: 92f735042e1cae38afe74364c036489fb7a81973
This commit is contained in:
Jordan Liggitt 2019-05-13 11:24:20 -04:00 committed by Kubernetes Publisher
parent 054e44a286
commit 6562ecd83a
8 changed files with 66 additions and 10 deletions

View File

@ -76,6 +76,8 @@ type ObjectInterfaces interface {
GetObjectDefaulter() runtime.ObjectDefaulter
// GetObjectConvertor is the ObjectConvertor appropriate for the requested object.
GetObjectConvertor() runtime.ObjectConvertor
// GetEquivalentResourceMapper is the EquivalentResourceMapper appropriate for finding equivalent resources and expected kind for the requested object.
GetEquivalentResourceMapper() runtime.EquivalentResourceMapper
}
// privateAnnotationsGetter is a private interface which allows users to get annotations from Attributes.

View File

@ -23,10 +23,11 @@ type RuntimeObjectInterfaces struct {
runtime.ObjectTyper
runtime.ObjectDefaulter
runtime.ObjectConvertor
runtime.EquivalentResourceMapper
}
func NewObjectInterfacesFromScheme(scheme *runtime.Scheme) ObjectInterfaces {
return &RuntimeObjectInterfaces{scheme, scheme, scheme, scheme}
return &RuntimeObjectInterfaces{scheme, scheme, scheme, scheme, runtime.NewEquivalentResourceRegistry()}
}
func (r *RuntimeObjectInterfaces) GetObjectCreater() runtime.ObjectCreater {
@ -41,3 +42,6 @@ func (r *RuntimeObjectInterfaces) GetObjectDefaulter() runtime.ObjectDefaulter {
func (r *RuntimeObjectInterfaces) GetObjectConvertor() runtime.ObjectConvertor {
return r.ObjectConvertor
}
func (r *RuntimeObjectInterfaces) GetEquivalentResourceMapper() runtime.EquivalentResourceMapper {
return r.EquivalentResourceMapper
}

View File

@ -229,6 +229,8 @@ func handleInternal(storage map[string]rest.Storage, admissionControl admission.
Linker: selfLinker,
RootScopedKinds: sets.NewString("SimpleRoot"),
EquivalentResourceRegistry: runtime.NewEquivalentResourceRegistry(),
ParameterCodec: parameterCodec,
Admit: admissionControl,
@ -3554,6 +3556,8 @@ func TestParentResourceIsRequired(t *testing.T) {
Linker: selfLinker,
RootScopedKinds: sets.NewString("SimpleRoot"),
EquivalentResourceRegistry: runtime.NewEquivalentResourceRegistry(),
Admit: admissionControl,
GroupVersion: newGroupVersion,
@ -3584,6 +3588,8 @@ func TestParentResourceIsRequired(t *testing.T) {
Typer: scheme,
Linker: selfLinker,
EquivalentResourceRegistry: runtime.NewEquivalentResourceRegistry(),
Admit: admissionControl,
GroupVersion: newGroupVersion,
@ -4301,6 +4307,8 @@ func TestXGSubresource(t *testing.T) {
Typer: scheme,
Linker: selfLinker,
EquivalentResourceRegistry: runtime.NewEquivalentResourceRegistry(),
ParameterCodec: parameterCodec,
Admit: admissionControl,

View File

@ -72,6 +72,8 @@ type APIGroupVersion struct {
Linker runtime.SelfLinker
UnsafeConvertor runtime.ObjectConvertor
EquivalentResourceRegistry runtime.EquivalentResourceRegistry
// Authorizer determines whether a user is allowed to make a certain request. The Handler does a preliminary
// authorization check using the request URI but it may be necessary to make additional checks, such as in
// the create-on-update case

View File

@ -57,6 +57,8 @@ type RequestScope struct {
UnsafeConvertor runtime.ObjectConvertor
Authorizer authorizer.Authorizer
EquivalentResourceMapper runtime.EquivalentResourceMapper
TableConvertor rest.TableConvertor
FieldManager *fieldmanager.FieldManager
@ -108,6 +110,9 @@ func (r *RequestScope) GetObjectCreater() runtime.ObjectCreater { return r.C
func (r *RequestScope) GetObjectTyper() runtime.ObjectTyper { return r.Typer }
func (r *RequestScope) GetObjectDefaulter() runtime.ObjectDefaulter { return r.Defaulter }
func (r *RequestScope) GetObjectConvertor() runtime.ObjectConvertor { return r.Convertor }
func (r *RequestScope) GetEquivalentResourceMapper() runtime.EquivalentResourceMapper {
return r.EquivalentResourceMapper
}
// ConnectResource returns a function that handles a connect request on a rest.Storage object.
func ConnectResource(connecter rest.Connecter, scope *RequestScope, admit admission.Interface, restPath string, isSubresource bool) http.HandlerFunc {

View File

@ -532,6 +532,8 @@ func (a *APIInstaller) registerResourceHandlers(path string, storage rest.Storag
UnsafeConvertor: a.group.UnsafeConvertor,
Authorizer: a.group.Authorizer,
EquivalentResourceMapper: a.group.EquivalentResourceRegistry,
// TODO: Check for the interface on storage
TableConvertor: tableProvider,
@ -925,6 +927,9 @@ func (a *APIInstaller) registerResourceHandlers(path string, storage rest.Storag
apiResource.Kind = gvk.Kind
}
// Record the existence of the GVR and the corresponding GVK
a.group.EquivalentResourceRegistry.RegisterKindFor(reqScope.Resource, reqScope.Subresource, fqKindToRegister)
return &apiResource, nil
}

View File

@ -35,6 +35,7 @@ import (
"k8s.io/klog"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/apimachinery/pkg/runtime/serializer"
"k8s.io/apimachinery/pkg/util/sets"
utilwaitgroup "k8s.io/apimachinery/pkg/util/waitgroup"
@ -188,6 +189,10 @@ type Config struct {
// kube-proxy, services, etc.) can reach the GenericAPIServer.
// If nil or 0.0.0.0, the host's default interface will be used.
PublicAddress net.IP
// EquivalentResourceRegistry provides information about resources equivalent to a given resource,
// and the kind associated with a given resource. As resources are installed, they are registered here.
EquivalentResourceRegistry runtime.EquivalentResourceRegistry
}
type RecommendedConfig struct {
@ -417,6 +422,21 @@ func (c *Config) Complete(informers informers.SharedInformerFactory) CompletedCo
c.RequestInfoResolver = NewRequestInfoResolver(c)
}
if c.EquivalentResourceRegistry == nil {
if c.RESTOptionsGetter == nil {
c.EquivalentResourceRegistry = runtime.NewEquivalentResourceRegistry()
} else {
c.EquivalentResourceRegistry = runtime.NewEquivalentResourceRegistryWithIdentity(func(groupResource schema.GroupResource) string {
// use the storage prefix as the key if possible
if opts, err := c.RESTOptionsGetter.GetRESTOptions(groupResource); err == nil {
return opts.ResourcePrefix
}
// otherwise return "" to use the default key (parent GV name)
return ""
})
}
}
return CompletedConfig{&completedConfig{c, informers}}
}
@ -436,6 +456,9 @@ func (c completedConfig) New(name string, delegationTarget DelegationTarget) (*G
if c.LoopbackClientConfig == nil {
return nil, fmt.Errorf("Genericapiserver.New() called with config.LoopbackClientConfig == nil")
}
if c.EquivalentResourceRegistry == nil {
return nil, fmt.Errorf("Genericapiserver.New() called with config.EquivalentResourceRegistry == nil")
}
handlerChainBuilder := func(handler http.Handler) http.Handler {
return c.BuildHandlerChainFunc(handler, c.Config)
@ -443,15 +466,16 @@ func (c completedConfig) New(name string, delegationTarget DelegationTarget) (*G
apiServerHandler := NewAPIServerHandler(name, c.Serializer, handlerChainBuilder, delegationTarget.UnprotectedHandler())
s := &GenericAPIServer{
discoveryAddresses: c.DiscoveryAddresses,
LoopbackClientConfig: c.LoopbackClientConfig,
legacyAPIGroupPrefixes: c.LegacyAPIGroupPrefixes,
admissionControl: c.AdmissionControl,
Serializer: c.Serializer,
AuditBackend: c.AuditBackend,
Authorizer: c.Authorization.Authorizer,
delegationTarget: delegationTarget,
HandlerChainWaitGroup: c.HandlerChainWaitGroup,
discoveryAddresses: c.DiscoveryAddresses,
LoopbackClientConfig: c.LoopbackClientConfig,
legacyAPIGroupPrefixes: c.LegacyAPIGroupPrefixes,
admissionControl: c.AdmissionControl,
Serializer: c.Serializer,
AuditBackend: c.AuditBackend,
Authorizer: c.Authorization.Authorizer,
delegationTarget: delegationTarget,
EquivalentResourceRegistry: c.EquivalentResourceRegistry,
HandlerChainWaitGroup: c.HandlerChainWaitGroup,
minRequestTimeout: time.Duration(c.MinRequestTimeout) * time.Second,
ShutdownTimeout: c.RequestTimeout,

View File

@ -157,6 +157,10 @@ type GenericAPIServer struct {
// the create-on-update case
Authorizer authorizer.Authorizer
// EquivalentResourceRegistry provides information about resources equivalent to a given resource,
// and the kind associated with a given resource. As resources are installed, they are registered here.
EquivalentResourceRegistry runtime.EquivalentResourceRegistry
// enableAPIResponseCompression indicates whether API Responses should support compression
// if the client requests it via Accept-Encoding
enableAPIResponseCompression bool
@ -467,6 +471,8 @@ func (s *GenericAPIServer) newAPIGroupVersion(apiGroupInfo *APIGroupInfo, groupV
Typer: apiGroupInfo.Scheme,
Linker: runtime.SelfLinker(meta.NewAccessor()),
EquivalentResourceRegistry: s.EquivalentResourceRegistry,
Admit: s.admissionControl,
MinRequestTimeout: s.minRequestTimeout,
EnableAPIResponseCompression: s.enableAPIResponseCompression,