mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-23 19:56:01 +00:00
Merge pull request #32622 from mbohlool/openapi
Automatic merge from submit-queue Move generated openAPI specs out of genericapiserver and make it configurable A follow up to #31468 Generated OpenAPI Spec does not belong to genericapiserver package. A new package "generated" created in hope of all generated codes goes into it in future. Openapi folder of that package contains generated definitions and generic API server will accept the definition map as a configuration parameter. Reference: #13414
This commit is contained in:
commit
735fca1c03
@ -45,6 +45,7 @@ import (
|
||||
"k8s.io/kubernetes/pkg/cloudprovider"
|
||||
"k8s.io/kubernetes/pkg/controller/informers"
|
||||
serviceaccountcontroller "k8s.io/kubernetes/pkg/controller/serviceaccount"
|
||||
"k8s.io/kubernetes/pkg/generated/openapi"
|
||||
"k8s.io/kubernetes/pkg/genericapiserver"
|
||||
"k8s.io/kubernetes/pkg/genericapiserver/authorizer"
|
||||
genericoptions "k8s.io/kubernetes/pkg/genericapiserver/options"
|
||||
@ -282,6 +283,8 @@ func Run(s *options.APIServer) error {
|
||||
genericConfig.ProxyTLSClientConfig = proxyTLSClientConfig
|
||||
genericConfig.Serializer = api.Codecs
|
||||
genericConfig.OpenAPIInfo.Title = "Kubernetes"
|
||||
genericConfig.OpenAPIDefinitions = openapi.OpenAPIDefinitions
|
||||
genericConfig.EnableOpenAPISupport = true
|
||||
|
||||
config := &master.Config{
|
||||
Config: genericConfig,
|
||||
|
@ -85,7 +85,7 @@ func Packages(context *generator.Context, arguments *args.GeneratorArgs) generat
|
||||
|
||||
`)...)
|
||||
|
||||
targets := []*types.Type{}
|
||||
targets := []*types.Package{}
|
||||
for i := range inputs {
|
||||
glog.V(5).Infof("considering pkg %q", i)
|
||||
pkg, ok := context.Universe[i]
|
||||
@ -93,11 +93,9 @@ func Packages(context *generator.Context, arguments *args.GeneratorArgs) generat
|
||||
// If the input had no Go files, for example.
|
||||
continue
|
||||
}
|
||||
for _, t := range pkg.Types {
|
||||
if hasOpenAPITagValue(t.CommentLines, tagTargetType) {
|
||||
glog.V(5).Infof("target type : %q", t)
|
||||
targets = append(targets, t)
|
||||
}
|
||||
if hasOpenAPITagValue(pkg.Comments, tagTargetType) || hasOpenAPITagValue(pkg.DocComments, tagTargetType) {
|
||||
glog.V(5).Infof("target package : %q", pkg)
|
||||
targets = append(targets, pkg)
|
||||
}
|
||||
}
|
||||
switch len(targets) {
|
||||
@ -106,7 +104,7 @@ func Packages(context *generator.Context, arguments *args.GeneratorArgs) generat
|
||||
// and build excluded the target package.
|
||||
return generator.Packages{}
|
||||
case 1:
|
||||
pkg := context.Universe[targets[0].Name.Package]
|
||||
pkg := targets[0]
|
||||
return generator.Packages{&generator.DefaultPackage{
|
||||
PackageName: strings.Split(filepath.Base(pkg.Path), ".")[0],
|
||||
PackagePath: pkg.Path,
|
||||
@ -144,27 +142,27 @@ const (
|
||||
// openApiGen produces a file with auto-generated OpenAPI functions.
|
||||
type openAPIGen struct {
|
||||
generator.DefaultGen
|
||||
// TargetType is the type that will get OpenAPIDefinitions method returning all definitions.
|
||||
targetType *types.Type
|
||||
imports namer.ImportTracker
|
||||
context *generator.Context
|
||||
// TargetPackage is the package that will get OpenAPIDefinitions variable contains all open API definitions.
|
||||
targetPackage *types.Package
|
||||
imports namer.ImportTracker
|
||||
context *generator.Context
|
||||
}
|
||||
|
||||
func NewOpenAPIGen(sanitizedName string, targetType *types.Type, context *generator.Context) generator.Generator {
|
||||
func NewOpenAPIGen(sanitizedName string, targetPackage *types.Package, context *generator.Context) generator.Generator {
|
||||
return &openAPIGen{
|
||||
DefaultGen: generator.DefaultGen{
|
||||
OptionalName: sanitizedName,
|
||||
},
|
||||
imports: generator.NewImportTracker(),
|
||||
targetType: targetType,
|
||||
context: context,
|
||||
imports: generator.NewImportTracker(),
|
||||
targetPackage: targetPackage,
|
||||
context: context,
|
||||
}
|
||||
}
|
||||
|
||||
func (g *openAPIGen) Namers(c *generator.Context) namer.NameSystems {
|
||||
// Have the raw namer for this file track what it imports.
|
||||
return namer.NameSystems{
|
||||
"raw": namer.NewRawNamer(g.targetType.Name.Package, g.imports),
|
||||
"raw": namer.NewRawNamer(g.targetPackage.Path, g.imports),
|
||||
}
|
||||
}
|
||||
|
||||
@ -177,10 +175,10 @@ func (g *openAPIGen) Filter(c *generator.Context, t *types.Type) bool {
|
||||
}
|
||||
|
||||
func (g *openAPIGen) isOtherPackage(pkg string) bool {
|
||||
if pkg == g.targetType.Name.Package {
|
||||
if pkg == g.targetPackage.Path {
|
||||
return false
|
||||
}
|
||||
if strings.HasSuffix(pkg, "\""+g.targetType.Name.Package+"\"") {
|
||||
if strings.HasSuffix(pkg, "\""+g.targetPackage.Path+"\"") {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
@ -205,14 +203,14 @@ func argsFromType(t *types.Type) generator.Args {
|
||||
|
||||
func (g *openAPIGen) Init(c *generator.Context, w io.Writer) error {
|
||||
sw := generator.NewSnippetWriter(w, c, "$", "$")
|
||||
sw.Do("func (_ $.type|raw$) OpenAPIDefinitions() *$.OpenAPIDefinitions|raw$ {\n", argsFromType(g.targetType))
|
||||
sw.Do("return &$.OpenAPIDefinitions|raw${\n", argsFromType(nil))
|
||||
sw.Do("var OpenAPIDefinitions *$.OpenAPIDefinitions|raw$ = ", argsFromType(nil))
|
||||
sw.Do("&$.OpenAPIDefinitions|raw${\n", argsFromType(nil))
|
||||
return sw.Error()
|
||||
}
|
||||
|
||||
func (g *openAPIGen) Finalize(c *generator.Context, w io.Writer) error {
|
||||
sw := generator.NewSnippetWriter(w, c, "$", "$")
|
||||
sw.Do("}\n}\n", nil)
|
||||
sw.Do("}\n", nil)
|
||||
return sw.Error()
|
||||
}
|
||||
|
||||
|
@ -34,6 +34,7 @@ import (
|
||||
"k8s.io/kubernetes/pkg/apis/rbac"
|
||||
"k8s.io/kubernetes/pkg/apiserver/authenticator"
|
||||
"k8s.io/kubernetes/pkg/controller/informers"
|
||||
"k8s.io/kubernetes/pkg/generated/openapi"
|
||||
"k8s.io/kubernetes/pkg/genericapiserver"
|
||||
"k8s.io/kubernetes/pkg/genericapiserver/authorizer"
|
||||
genericoptions "k8s.io/kubernetes/pkg/genericapiserver/options"
|
||||
@ -185,6 +186,8 @@ func Run(s *options.ServerRunOptions) error {
|
||||
genericConfig.APIResourceConfigSource = storageFactory.APIResourceConfigSource
|
||||
genericConfig.MasterServiceNamespace = s.MasterServiceNamespace
|
||||
genericConfig.Serializer = api.Codecs
|
||||
genericConfig.OpenAPIDefinitions = openapi.OpenAPIDefinitions
|
||||
genericConfig.EnableOpenAPISupport = true
|
||||
|
||||
// TODO: Move this to generic api server (Need to move the command line flag).
|
||||
if s.EnableWatchCache {
|
||||
|
19
pkg/generated/doc.go
Normal file
19
pkg/generated/doc.go
Normal file
@ -0,0 +1,19 @@
|
||||
/*
|
||||
Copyright 2016 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// generated package is the destination for all generated files. Not all generated files are currently use this package
|
||||
// but the plan is to move as much of them as possible to this package.
|
||||
package generated
|
19
pkg/generated/openapi/doc.go
Normal file
19
pkg/generated/openapi/doc.go
Normal file
@ -0,0 +1,19 @@
|
||||
/*
|
||||
Copyright 2016 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// openapi generated definitions.
|
||||
// +k8s:openapi-gen=target
|
||||
package openapi
|
18338
pkg/generated/openapi/zz_generated.openapi.go
Normal file
18338
pkg/generated/openapi/zz_generated.openapi.go
Normal file
File diff suppressed because it is too large
Load Diff
@ -32,6 +32,7 @@ import (
|
||||
"github.com/golang/glog"
|
||||
"gopkg.in/natefinch/lumberjack.v2"
|
||||
|
||||
"k8s.io/kubernetes/cmd/libs/go2idl/openapi-gen/generators/common"
|
||||
"k8s.io/kubernetes/pkg/admission"
|
||||
"k8s.io/kubernetes/pkg/api"
|
||||
"k8s.io/kubernetes/pkg/api/unversioned"
|
||||
@ -157,6 +158,10 @@ type Config struct {
|
||||
|
||||
// OpenAPIDefaultResponse will be used if an web service operation does not have any responses listed.
|
||||
OpenAPIDefaultResponse spec.Response
|
||||
|
||||
// OpenAPIDefinitions is a map of type to OpenAPI spec for all types used in this API server. Failure to provide
|
||||
// this map or any of the models used by the server APIs will result in spec generation failure.
|
||||
OpenAPIDefinitions *common.OpenAPIDefinitions
|
||||
}
|
||||
|
||||
func NewConfig(options *options.ServerRunOptions) *Config {
|
||||
@ -183,7 +188,6 @@ func NewConfig(options *options.ServerRunOptions) *Config {
|
||||
ReadWritePort: options.SecurePort,
|
||||
ServiceClusterIPRange: &options.ServiceClusterIPRange,
|
||||
ServiceNodePortRange: options.ServiceNodePortRange,
|
||||
EnableOpenAPISupport: true,
|
||||
OpenAPIDefaultResponse: spec.Response{
|
||||
ResponseProps: spec.ResponseProps{
|
||||
Description: "Default Response."}},
|
||||
@ -308,6 +312,7 @@ func (c Config) New() (*GenericAPIServer, error) {
|
||||
enableOpenAPISupport: c.EnableOpenAPISupport,
|
||||
openAPIInfo: c.OpenAPIInfo,
|
||||
openAPIDefaultResponse: c.OpenAPIDefaultResponse,
|
||||
openAPIDefinitions: c.OpenAPIDefinitions,
|
||||
}
|
||||
|
||||
if c.EnableWatchCache {
|
||||
|
@ -35,6 +35,7 @@ import (
|
||||
"github.com/golang/glog"
|
||||
|
||||
"github.com/go-openapi/spec"
|
||||
"k8s.io/kubernetes/cmd/libs/go2idl/openapi-gen/generators/common"
|
||||
"k8s.io/kubernetes/pkg/admission"
|
||||
"k8s.io/kubernetes/pkg/api"
|
||||
"k8s.io/kubernetes/pkg/api/rest"
|
||||
@ -171,6 +172,7 @@ type GenericAPIServer struct {
|
||||
PostStartHooks map[string]PostStartHookFunc
|
||||
postStartHookLock sync.Mutex
|
||||
postStartHooksCalled bool
|
||||
openAPIDefinitions *common.OpenAPIDefinitions
|
||||
}
|
||||
|
||||
func (s *GenericAPIServer) StorageDecorator() generic.StorageDecorator {
|
||||
@ -565,24 +567,26 @@ func (s *GenericAPIServer) InstallOpenAPI() {
|
||||
info := s.openAPIInfo
|
||||
info.Title = info.Title + " " + w.RootPath()
|
||||
err := openapi.RegisterOpenAPIService(&openapi.Config{
|
||||
OpenAPIServePath: w.RootPath() + "/swagger.json",
|
||||
WebServices: []*restful.WebService{w},
|
||||
ProtocolList: []string{"https"},
|
||||
IgnorePrefixes: []string{"/swaggerapi"},
|
||||
Info: &info,
|
||||
DefaultResponse: &s.openAPIDefaultResponse,
|
||||
OpenAPIServePath: w.RootPath() + "/swagger.json",
|
||||
WebServices: []*restful.WebService{w},
|
||||
ProtocolList: []string{"https"},
|
||||
IgnorePrefixes: []string{"/swaggerapi"},
|
||||
Info: &info,
|
||||
DefaultResponse: &s.openAPIDefaultResponse,
|
||||
OpenAPIDefinitions: s.openAPIDefinitions,
|
||||
}, s.HandlerContainer)
|
||||
if err != nil {
|
||||
glog.Fatalf("Failed to register open api spec for %v: %v", w.RootPath(), err)
|
||||
}
|
||||
}
|
||||
err := openapi.RegisterOpenAPIService(&openapi.Config{
|
||||
OpenAPIServePath: "/swagger.json",
|
||||
WebServices: s.HandlerContainer.RegisteredWebServices(),
|
||||
ProtocolList: []string{"https"},
|
||||
IgnorePrefixes: []string{"/swaggerapi"},
|
||||
Info: &s.openAPIInfo,
|
||||
DefaultResponse: &s.openAPIDefaultResponse,
|
||||
OpenAPIServePath: "/swagger.json",
|
||||
WebServices: s.HandlerContainer.RegisteredWebServices(),
|
||||
ProtocolList: []string{"https"},
|
||||
IgnorePrefixes: []string{"/swaggerapi"},
|
||||
Info: &s.openAPIInfo,
|
||||
DefaultResponse: &s.openAPIDefaultResponse,
|
||||
OpenAPIDefinitions: s.openAPIDefinitions,
|
||||
}, s.HandlerContainer)
|
||||
if err != nil {
|
||||
glog.Fatalf("Failed to register open api spec for root: %v", err)
|
||||
|
@ -50,14 +50,16 @@ type Config struct {
|
||||
DefaultResponse *spec.Response
|
||||
// List of webservice's path prefixes to ignore
|
||||
IgnorePrefixes []string
|
||||
|
||||
// OpenAPIDefinitions should provide definition for all models used by routes. Failure to provide this map
|
||||
// or any of the models will result in spec generation failure.
|
||||
OpenAPIDefinitions *common.OpenAPIDefinitions
|
||||
}
|
||||
|
||||
// +k8s:openapi-gen=target
|
||||
type openAPI struct {
|
||||
config *Config
|
||||
swagger *spec.Swagger
|
||||
protocolList []string
|
||||
openAPIDefinitions *common.OpenAPIDefinitions
|
||||
config *Config
|
||||
swagger *spec.Swagger
|
||||
protocolList []string
|
||||
}
|
||||
|
||||
// RegisterOpenAPIService registers a handler to provides standard OpenAPI specification.
|
||||
@ -91,17 +93,10 @@ func RegisterOpenAPIService(config *Config, containers *restful.Container) (err
|
||||
}
|
||||
|
||||
func (o *openAPI) init() error {
|
||||
if o.openAPIDefinitions == nil {
|
||||
// Compilation error here means the code generator need to run first.
|
||||
o.openAPIDefinitions = o.OpenAPIDefinitions()
|
||||
}
|
||||
err := o.buildPaths()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// no need to the keep type list in memory
|
||||
o.openAPIDefinitions = nil
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -109,7 +104,7 @@ func (o *openAPI) buildDefinitionRecursively(name string) error {
|
||||
if _, ok := o.swagger.Definitions[name]; ok {
|
||||
return nil
|
||||
}
|
||||
if item, ok := (*o.openAPIDefinitions)[name]; ok {
|
||||
if item, ok := (*o.config.OpenAPIDefinitions)[name]; ok {
|
||||
o.swagger.Definitions[name] = item.Schema
|
||||
for _, v := range item.Dependencies {
|
||||
if err := o.buildDefinitionRecursively(v); err != nil {
|
||||
|
@ -42,10 +42,6 @@ func setUp(t *testing.T, fullMethods bool) (openAPI, *assert.Assertions) {
|
||||
Info: config.Info,
|
||||
},
|
||||
},
|
||||
openAPIDefinitions: &common.OpenAPIDefinitions{
|
||||
"openapi.TestInput": *TestInput{}.OpenAPIDefinition(),
|
||||
"openapi.TestOutput": *TestOutput{}.OpenAPIDefinition(),
|
||||
},
|
||||
}, assert
|
||||
}
|
||||
|
||||
@ -193,6 +189,10 @@ func getConfig(fullMethods bool) *Config {
|
||||
Description: "Test API",
|
||||
},
|
||||
},
|
||||
OpenAPIDefinitions: &common.OpenAPIDefinitions{
|
||||
"openapi.TestInput": *TestInput{}.OpenAPIDefinition(),
|
||||
"openapi.TestOutput": *TestOutput{}.OpenAPIDefinition(),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -71,6 +71,7 @@ import (
|
||||
"github.com/go-openapi/validate"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"golang.org/x/net/context"
|
||||
"k8s.io/kubernetes/pkg/generated/openapi"
|
||||
)
|
||||
|
||||
// setUp is a convience function for setting up for (most) tests.
|
||||
@ -1251,6 +1252,7 @@ func TestValidOpenAPISpec(t *testing.T) {
|
||||
_, etcdserver, config, assert := setUp(t)
|
||||
defer etcdserver.Terminate(t)
|
||||
|
||||
config.OpenAPIDefinitions = openapi.OpenAPIDefinitions
|
||||
config.EnableOpenAPISupport = true
|
||||
config.EnableIndex = true
|
||||
config.OpenAPIInfo = spec.Info{
|
||||
|
@ -58,6 +58,7 @@ import (
|
||||
|
||||
"github.com/go-openapi/spec"
|
||||
"github.com/pborman/uuid"
|
||||
"k8s.io/kubernetes/pkg/generated/openapi"
|
||||
)
|
||||
|
||||
const (
|
||||
@ -235,6 +236,8 @@ func NewMasterConfig() *master.Config {
|
||||
ServiceClusterIPRange: parseCIDROrDie("10.0.0.0/24"),
|
||||
ServiceNodePortRange: utilnet.PortRange{Base: 30000, Size: 2768},
|
||||
EnableVersion: true,
|
||||
OpenAPIDefinitions: openapi.OpenAPIDefinitions,
|
||||
EnableOpenAPISupport: true,
|
||||
},
|
||||
KubeletClient: kubeletclient.FakeKubeletClient{},
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user