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 GetObjectDefaulter() runtime.ObjectDefaulter
// GetObjectConvertor is the ObjectConvertor appropriate for the requested object. // GetObjectConvertor is the ObjectConvertor appropriate for the requested object.
GetObjectConvertor() runtime.ObjectConvertor 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. // 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.ObjectTyper
runtime.ObjectDefaulter runtime.ObjectDefaulter
runtime.ObjectConvertor runtime.ObjectConvertor
runtime.EquivalentResourceMapper
} }
func NewObjectInterfacesFromScheme(scheme *runtime.Scheme) ObjectInterfaces { 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 { func (r *RuntimeObjectInterfaces) GetObjectCreater() runtime.ObjectCreater {
@ -41,3 +42,6 @@ func (r *RuntimeObjectInterfaces) GetObjectDefaulter() runtime.ObjectDefaulter {
func (r *RuntimeObjectInterfaces) GetObjectConvertor() runtime.ObjectConvertor { func (r *RuntimeObjectInterfaces) GetObjectConvertor() runtime.ObjectConvertor {
return r.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, Linker: selfLinker,
RootScopedKinds: sets.NewString("SimpleRoot"), RootScopedKinds: sets.NewString("SimpleRoot"),
EquivalentResourceRegistry: runtime.NewEquivalentResourceRegistry(),
ParameterCodec: parameterCodec, ParameterCodec: parameterCodec,
Admit: admissionControl, Admit: admissionControl,
@ -3554,6 +3556,8 @@ func TestParentResourceIsRequired(t *testing.T) {
Linker: selfLinker, Linker: selfLinker,
RootScopedKinds: sets.NewString("SimpleRoot"), RootScopedKinds: sets.NewString("SimpleRoot"),
EquivalentResourceRegistry: runtime.NewEquivalentResourceRegistry(),
Admit: admissionControl, Admit: admissionControl,
GroupVersion: newGroupVersion, GroupVersion: newGroupVersion,
@ -3584,6 +3588,8 @@ func TestParentResourceIsRequired(t *testing.T) {
Typer: scheme, Typer: scheme,
Linker: selfLinker, Linker: selfLinker,
EquivalentResourceRegistry: runtime.NewEquivalentResourceRegistry(),
Admit: admissionControl, Admit: admissionControl,
GroupVersion: newGroupVersion, GroupVersion: newGroupVersion,
@ -4301,6 +4307,8 @@ func TestXGSubresource(t *testing.T) {
Typer: scheme, Typer: scheme,
Linker: selfLinker, Linker: selfLinker,
EquivalentResourceRegistry: runtime.NewEquivalentResourceRegistry(),
ParameterCodec: parameterCodec, ParameterCodec: parameterCodec,
Admit: admissionControl, Admit: admissionControl,

View File

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

View File

@ -57,6 +57,8 @@ type RequestScope struct {
UnsafeConvertor runtime.ObjectConvertor UnsafeConvertor runtime.ObjectConvertor
Authorizer authorizer.Authorizer Authorizer authorizer.Authorizer
EquivalentResourceMapper runtime.EquivalentResourceMapper
TableConvertor rest.TableConvertor TableConvertor rest.TableConvertor
FieldManager *fieldmanager.FieldManager 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) GetObjectTyper() runtime.ObjectTyper { return r.Typer }
func (r *RequestScope) GetObjectDefaulter() runtime.ObjectDefaulter { return r.Defaulter } func (r *RequestScope) GetObjectDefaulter() runtime.ObjectDefaulter { return r.Defaulter }
func (r *RequestScope) GetObjectConvertor() runtime.ObjectConvertor { return r.Convertor } 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. // 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 { 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, UnsafeConvertor: a.group.UnsafeConvertor,
Authorizer: a.group.Authorizer, Authorizer: a.group.Authorizer,
EquivalentResourceMapper: a.group.EquivalentResourceRegistry,
// TODO: Check for the interface on storage // TODO: Check for the interface on storage
TableConvertor: tableProvider, TableConvertor: tableProvider,
@ -925,6 +927,9 @@ func (a *APIInstaller) registerResourceHandlers(path string, storage rest.Storag
apiResource.Kind = gvk.Kind 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 return &apiResource, nil
} }

View File

@ -35,6 +35,7 @@ import (
"k8s.io/klog" "k8s.io/klog"
"k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/apimachinery/pkg/runtime/serializer" "k8s.io/apimachinery/pkg/runtime/serializer"
"k8s.io/apimachinery/pkg/util/sets" "k8s.io/apimachinery/pkg/util/sets"
utilwaitgroup "k8s.io/apimachinery/pkg/util/waitgroup" utilwaitgroup "k8s.io/apimachinery/pkg/util/waitgroup"
@ -188,6 +189,10 @@ type Config struct {
// kube-proxy, services, etc.) can reach the GenericAPIServer. // kube-proxy, services, etc.) can reach the GenericAPIServer.
// If nil or 0.0.0.0, the host's default interface will be used. // If nil or 0.0.0.0, the host's default interface will be used.
PublicAddress net.IP 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 { type RecommendedConfig struct {
@ -417,6 +422,21 @@ func (c *Config) Complete(informers informers.SharedInformerFactory) CompletedCo
c.RequestInfoResolver = NewRequestInfoResolver(c) 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}} return CompletedConfig{&completedConfig{c, informers}}
} }
@ -436,6 +456,9 @@ func (c completedConfig) New(name string, delegationTarget DelegationTarget) (*G
if c.LoopbackClientConfig == nil { if c.LoopbackClientConfig == nil {
return nil, fmt.Errorf("Genericapiserver.New() called with config.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 { handlerChainBuilder := func(handler http.Handler) http.Handler {
return c.BuildHandlerChainFunc(handler, c.Config) 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()) apiServerHandler := NewAPIServerHandler(name, c.Serializer, handlerChainBuilder, delegationTarget.UnprotectedHandler())
s := &GenericAPIServer{ s := &GenericAPIServer{
discoveryAddresses: c.DiscoveryAddresses, discoveryAddresses: c.DiscoveryAddresses,
LoopbackClientConfig: c.LoopbackClientConfig, LoopbackClientConfig: c.LoopbackClientConfig,
legacyAPIGroupPrefixes: c.LegacyAPIGroupPrefixes, legacyAPIGroupPrefixes: c.LegacyAPIGroupPrefixes,
admissionControl: c.AdmissionControl, admissionControl: c.AdmissionControl,
Serializer: c.Serializer, Serializer: c.Serializer,
AuditBackend: c.AuditBackend, AuditBackend: c.AuditBackend,
Authorizer: c.Authorization.Authorizer, Authorizer: c.Authorization.Authorizer,
delegationTarget: delegationTarget, delegationTarget: delegationTarget,
HandlerChainWaitGroup: c.HandlerChainWaitGroup, EquivalentResourceRegistry: c.EquivalentResourceRegistry,
HandlerChainWaitGroup: c.HandlerChainWaitGroup,
minRequestTimeout: time.Duration(c.MinRequestTimeout) * time.Second, minRequestTimeout: time.Duration(c.MinRequestTimeout) * time.Second,
ShutdownTimeout: c.RequestTimeout, ShutdownTimeout: c.RequestTimeout,

View File

@ -157,6 +157,10 @@ type GenericAPIServer struct {
// the create-on-update case // the create-on-update case
Authorizer authorizer.Authorizer 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 // enableAPIResponseCompression indicates whether API Responses should support compression
// if the client requests it via Accept-Encoding // if the client requests it via Accept-Encoding
enableAPIResponseCompression bool enableAPIResponseCompression bool
@ -467,6 +471,8 @@ func (s *GenericAPIServer) newAPIGroupVersion(apiGroupInfo *APIGroupInfo, groupV
Typer: apiGroupInfo.Scheme, Typer: apiGroupInfo.Scheme,
Linker: runtime.SelfLinker(meta.NewAccessor()), Linker: runtime.SelfLinker(meta.NewAccessor()),
EquivalentResourceRegistry: s.EquivalentResourceRegistry,
Admit: s.admissionControl, Admit: s.admissionControl,
MinRequestTimeout: s.minRequestTimeout, MinRequestTimeout: s.minRequestTimeout,
EnableAPIResponseCompression: s.enableAPIResponseCompression, EnableAPIResponseCompression: s.enableAPIResponseCompression,