diff --git a/staging/src/k8s.io/apiserver/pkg/endpoints/BUILD b/staging/src/k8s.io/apiserver/pkg/endpoints/BUILD index ef6df76066..85240fc028 100644 --- a/staging/src/k8s.io/apiserver/pkg/endpoints/BUILD +++ b/staging/src/k8s.io/apiserver/pkg/endpoints/BUILD @@ -85,6 +85,8 @@ go_library( "//vendor/github.com/emicklei/go-restful:go_default_library", "//vendor/k8s.io/kube-openapi/pkg/builder:go_default_library", "//vendor/k8s.io/kube-openapi/pkg/common:go_default_library", + "//vendor/k8s.io/kube-openapi/pkg/util:go_default_library", + "//vendor/k8s.io/kube-openapi/pkg/util/proto:go_default_library", ], ) diff --git a/staging/src/k8s.io/apiserver/pkg/endpoints/installer.go b/staging/src/k8s.io/apiserver/pkg/endpoints/installer.go index 4a3c498671..ca08320ffb 100644 --- a/staging/src/k8s.io/apiserver/pkg/endpoints/installer.go +++ b/staging/src/k8s.io/apiserver/pkg/endpoints/installer.go @@ -41,6 +41,8 @@ import ( genericfilters "k8s.io/apiserver/pkg/server/filters" utilopenapi "k8s.io/apiserver/pkg/util/openapi" openapibuilder "k8s.io/kube-openapi/pkg/builder" + openapiutil "k8s.io/kube-openapi/pkg/util" + openapiproto "k8s.io/kube-openapi/pkg/util/proto" ) const ( @@ -498,15 +500,9 @@ func (a *APIInstaller) registerResourceHandlers(path string, storage rest.Storag if a.group.MetaGroupVersion != nil { reqScope.MetaGroupVersion = *a.group.MetaGroupVersion } - if a.group.OpenAPIConfig != nil { - openAPIDefinitions, err := openapibuilder.BuildOpenAPIDefinitionsForResource(defaultVersionedObject, a.group.OpenAPIConfig) - if err != nil { - return nil, fmt.Errorf("unable to build openapi definitions for %v: %v", fqKindToRegister, err) - } - reqScope.OpenAPISchema, err = utilopenapi.ToProtoSchema(openAPIDefinitions, fqKindToRegister) - if err != nil { - return nil, fmt.Errorf("unable to get openapi schema for %v: %v", fqKindToRegister, err) - } + reqScope.OpenAPISchema, err = a.getOpenAPISchema(ws.RootPath(), resource, fqKindToRegister, defaultVersionedObject) + if err != nil { + return nil, fmt.Errorf("unable to get openapi schema for %v: %v", fqKindToRegister, err) } for _, action := range actions { producedObject := storageMeta.ProducesObject(action.Verb) @@ -852,6 +848,24 @@ func (a *APIInstaller) registerResourceHandlers(path string, storage rest.Storag return &apiResource, nil } +// getOpenAPISchema builds the openapi schema for a single resource model to be given to each handler. It will +// return nil if the apiserver doesn't have openapi enabled, or if the specific path should be ignored by openapi. +func (a *APIInstaller) getOpenAPISchema(rootPath, resource string, kind schema.GroupVersionKind, sampleObject interface{}) (openapiproto.Schema, error) { + path := gpath.Join(rootPath, resource) + if a.group.OpenAPIConfig == nil { + return nil, nil + } + pathsToIgnore := openapiutil.NewTrie(a.group.OpenAPIConfig.IgnorePrefixes) + if pathsToIgnore.HasPrefix(path) { + return nil, nil + } + openAPIDefinitions, err := openapibuilder.BuildOpenAPIDefinitionsForResource(sampleObject, a.group.OpenAPIConfig) + if err != nil { + return nil, err + } + return utilopenapi.ToProtoSchema(openAPIDefinitions, kind) +} + // indirectArbitraryPointer returns *ptrToObject for an arbitrary pointer func indirectArbitraryPointer(ptrToObject interface{}) interface{} { return reflect.Indirect(reflect.ValueOf(ptrToObject)).Interface()