diff --git a/Godeps/Godeps.json b/Godeps/Godeps.json index 8439b23c035..6a83e9e40ee 100644 --- a/Godeps/Godeps.json +++ b/Godeps/Godeps.json @@ -3265,35 +3265,35 @@ }, { "ImportPath": "k8s.io/kube-openapi/pkg/aggregator", - "Rev": "a07b7bbb58e7fdc5144f8d7046331d29fc9ad3b3" + "Rev": "50ae88d24ede7b8bad68e23c805b5d3da5c8abaf" }, { "ImportPath": "k8s.io/kube-openapi/pkg/builder", - "Rev": "a07b7bbb58e7fdc5144f8d7046331d29fc9ad3b3" + "Rev": "50ae88d24ede7b8bad68e23c805b5d3da5c8abaf" }, { "ImportPath": "k8s.io/kube-openapi/pkg/common", - "Rev": "a07b7bbb58e7fdc5144f8d7046331d29fc9ad3b3" + "Rev": "50ae88d24ede7b8bad68e23c805b5d3da5c8abaf" }, { "ImportPath": "k8s.io/kube-openapi/pkg/generators", - "Rev": "a07b7bbb58e7fdc5144f8d7046331d29fc9ad3b3" + "Rev": "50ae88d24ede7b8bad68e23c805b5d3da5c8abaf" }, { "ImportPath": "k8s.io/kube-openapi/pkg/handler", - "Rev": "a07b7bbb58e7fdc5144f8d7046331d29fc9ad3b3" + "Rev": "50ae88d24ede7b8bad68e23c805b5d3da5c8abaf" }, { "ImportPath": "k8s.io/kube-openapi/pkg/util", - "Rev": "a07b7bbb58e7fdc5144f8d7046331d29fc9ad3b3" + "Rev": "50ae88d24ede7b8bad68e23c805b5d3da5c8abaf" }, { "ImportPath": "k8s.io/kube-openapi/pkg/util/proto", - "Rev": "a07b7bbb58e7fdc5144f8d7046331d29fc9ad3b3" + "Rev": "50ae88d24ede7b8bad68e23c805b5d3da5c8abaf" }, { "ImportPath": "k8s.io/kube-openapi/pkg/util/proto/validation", - "Rev": "a07b7bbb58e7fdc5144f8d7046331d29fc9ad3b3" + "Rev": "50ae88d24ede7b8bad68e23c805b5d3da5c8abaf" }, { "ImportPath": "k8s.io/utils/clock", diff --git a/staging/src/k8s.io/apiextensions-apiserver/Godeps/Godeps.json b/staging/src/k8s.io/apiextensions-apiserver/Godeps/Godeps.json index 801ecbcf2d8..612cc283e15 100644 --- a/staging/src/k8s.io/apiextensions-apiserver/Godeps/Godeps.json +++ b/staging/src/k8s.io/apiextensions-apiserver/Godeps/Godeps.json @@ -1640,23 +1640,23 @@ }, { "ImportPath": "k8s.io/kube-openapi/pkg/builder", - "Rev": "a07b7bbb58e7fdc5144f8d7046331d29fc9ad3b3" + "Rev": "50ae88d24ede7b8bad68e23c805b5d3da5c8abaf" }, { "ImportPath": "k8s.io/kube-openapi/pkg/common", - "Rev": "a07b7bbb58e7fdc5144f8d7046331d29fc9ad3b3" + "Rev": "50ae88d24ede7b8bad68e23c805b5d3da5c8abaf" }, { "ImportPath": "k8s.io/kube-openapi/pkg/handler", - "Rev": "a07b7bbb58e7fdc5144f8d7046331d29fc9ad3b3" + "Rev": "50ae88d24ede7b8bad68e23c805b5d3da5c8abaf" }, { "ImportPath": "k8s.io/kube-openapi/pkg/util", - "Rev": "a07b7bbb58e7fdc5144f8d7046331d29fc9ad3b3" + "Rev": "50ae88d24ede7b8bad68e23c805b5d3da5c8abaf" }, { "ImportPath": "k8s.io/kube-openapi/pkg/util/proto", - "Rev": "a07b7bbb58e7fdc5144f8d7046331d29fc9ad3b3" + "Rev": "50ae88d24ede7b8bad68e23c805b5d3da5c8abaf" }, { "ImportPath": "k8s.io/apimachinery/pkg/api/equality", diff --git a/staging/src/k8s.io/apimachinery/Godeps/Godeps.json b/staging/src/k8s.io/apimachinery/Godeps/Godeps.json index 5ba1aa54698..8c309a8d0a9 100644 --- a/staging/src/k8s.io/apimachinery/Godeps/Godeps.json +++ b/staging/src/k8s.io/apimachinery/Godeps/Godeps.json @@ -172,7 +172,7 @@ }, { "ImportPath": "k8s.io/kube-openapi/pkg/util/proto", - "Rev": "a07b7bbb58e7fdc5144f8d7046331d29fc9ad3b3" + "Rev": "50ae88d24ede7b8bad68e23c805b5d3da5c8abaf" } ] } diff --git a/staging/src/k8s.io/apiserver/Godeps/Godeps.json b/staging/src/k8s.io/apiserver/Godeps/Godeps.json index 28762db80e6..6a99134f754 100644 --- a/staging/src/k8s.io/apiserver/Godeps/Godeps.json +++ b/staging/src/k8s.io/apiserver/Godeps/Godeps.json @@ -1736,23 +1736,23 @@ }, { "ImportPath": "k8s.io/kube-openapi/pkg/builder", - "Rev": "a07b7bbb58e7fdc5144f8d7046331d29fc9ad3b3" + "Rev": "50ae88d24ede7b8bad68e23c805b5d3da5c8abaf" }, { "ImportPath": "k8s.io/kube-openapi/pkg/common", - "Rev": "a07b7bbb58e7fdc5144f8d7046331d29fc9ad3b3" + "Rev": "50ae88d24ede7b8bad68e23c805b5d3da5c8abaf" }, { "ImportPath": "k8s.io/kube-openapi/pkg/handler", - "Rev": "a07b7bbb58e7fdc5144f8d7046331d29fc9ad3b3" + "Rev": "50ae88d24ede7b8bad68e23c805b5d3da5c8abaf" }, { "ImportPath": "k8s.io/kube-openapi/pkg/util", - "Rev": "a07b7bbb58e7fdc5144f8d7046331d29fc9ad3b3" + "Rev": "50ae88d24ede7b8bad68e23c805b5d3da5c8abaf" }, { "ImportPath": "k8s.io/kube-openapi/pkg/util/proto", - "Rev": "a07b7bbb58e7fdc5144f8d7046331d29fc9ad3b3" + "Rev": "50ae88d24ede7b8bad68e23c805b5d3da5c8abaf" }, { "ImportPath": "k8s.io/client-go/discovery", diff --git a/staging/src/k8s.io/client-go/Godeps/Godeps.json b/staging/src/k8s.io/client-go/Godeps/Godeps.json index 613133f3b88..5e09199bbf6 100644 --- a/staging/src/k8s.io/client-go/Godeps/Godeps.json +++ b/staging/src/k8s.io/client-go/Godeps/Godeps.json @@ -612,7 +612,7 @@ }, { "ImportPath": "k8s.io/kube-openapi/pkg/util/proto", - "Rev": "a07b7bbb58e7fdc5144f8d7046331d29fc9ad3b3" + "Rev": "50ae88d24ede7b8bad68e23c805b5d3da5c8abaf" } ] } diff --git a/staging/src/k8s.io/code-generator/Godeps/Godeps.json b/staging/src/k8s.io/code-generator/Godeps/Godeps.json index 4595525e23d..231e0f3d94f 100644 --- a/staging/src/k8s.io/code-generator/Godeps/Godeps.json +++ b/staging/src/k8s.io/code-generator/Godeps/Godeps.json @@ -260,11 +260,11 @@ }, { "ImportPath": "k8s.io/kube-openapi/pkg/common", - "Rev": "a07b7bbb58e7fdc5144f8d7046331d29fc9ad3b3" + "Rev": "50ae88d24ede7b8bad68e23c805b5d3da5c8abaf" }, { "ImportPath": "k8s.io/kube-openapi/pkg/generators", - "Rev": "a07b7bbb58e7fdc5144f8d7046331d29fc9ad3b3" + "Rev": "50ae88d24ede7b8bad68e23c805b5d3da5c8abaf" } ] } diff --git a/staging/src/k8s.io/kube-aggregator/Godeps/Godeps.json b/staging/src/k8s.io/kube-aggregator/Godeps/Godeps.json index 8cf207260db..e3137d03d8d 100644 --- a/staging/src/k8s.io/kube-aggregator/Godeps/Godeps.json +++ b/staging/src/k8s.io/kube-aggregator/Godeps/Godeps.json @@ -1628,27 +1628,27 @@ }, { "ImportPath": "k8s.io/kube-openapi/pkg/aggregator", - "Rev": "a07b7bbb58e7fdc5144f8d7046331d29fc9ad3b3" + "Rev": "50ae88d24ede7b8bad68e23c805b5d3da5c8abaf" }, { "ImportPath": "k8s.io/kube-openapi/pkg/builder", - "Rev": "a07b7bbb58e7fdc5144f8d7046331d29fc9ad3b3" + "Rev": "50ae88d24ede7b8bad68e23c805b5d3da5c8abaf" }, { "ImportPath": "k8s.io/kube-openapi/pkg/common", - "Rev": "a07b7bbb58e7fdc5144f8d7046331d29fc9ad3b3" + "Rev": "50ae88d24ede7b8bad68e23c805b5d3da5c8abaf" }, { "ImportPath": "k8s.io/kube-openapi/pkg/handler", - "Rev": "a07b7bbb58e7fdc5144f8d7046331d29fc9ad3b3" + "Rev": "50ae88d24ede7b8bad68e23c805b5d3da5c8abaf" }, { "ImportPath": "k8s.io/kube-openapi/pkg/util", - "Rev": "a07b7bbb58e7fdc5144f8d7046331d29fc9ad3b3" + "Rev": "50ae88d24ede7b8bad68e23c805b5d3da5c8abaf" }, { "ImportPath": "k8s.io/kube-openapi/pkg/util/proto", - "Rev": "a07b7bbb58e7fdc5144f8d7046331d29fc9ad3b3" + "Rev": "50ae88d24ede7b8bad68e23c805b5d3da5c8abaf" } ] } diff --git a/staging/src/k8s.io/sample-apiserver/Godeps/Godeps.json b/staging/src/k8s.io/sample-apiserver/Godeps/Godeps.json index 5c6e4a66fe5..80602646474 100644 --- a/staging/src/k8s.io/sample-apiserver/Godeps/Godeps.json +++ b/staging/src/k8s.io/sample-apiserver/Godeps/Godeps.json @@ -1616,23 +1616,23 @@ }, { "ImportPath": "k8s.io/kube-openapi/pkg/builder", - "Rev": "a07b7bbb58e7fdc5144f8d7046331d29fc9ad3b3" + "Rev": "50ae88d24ede7b8bad68e23c805b5d3da5c8abaf" }, { "ImportPath": "k8s.io/kube-openapi/pkg/common", - "Rev": "a07b7bbb58e7fdc5144f8d7046331d29fc9ad3b3" + "Rev": "50ae88d24ede7b8bad68e23c805b5d3da5c8abaf" }, { "ImportPath": "k8s.io/kube-openapi/pkg/handler", - "Rev": "a07b7bbb58e7fdc5144f8d7046331d29fc9ad3b3" + "Rev": "50ae88d24ede7b8bad68e23c805b5d3da5c8abaf" }, { "ImportPath": "k8s.io/kube-openapi/pkg/util", - "Rev": "a07b7bbb58e7fdc5144f8d7046331d29fc9ad3b3" + "Rev": "50ae88d24ede7b8bad68e23c805b5d3da5c8abaf" }, { "ImportPath": "k8s.io/kube-openapi/pkg/util/proto", - "Rev": "a07b7bbb58e7fdc5144f8d7046331d29fc9ad3b3" + "Rev": "50ae88d24ede7b8bad68e23c805b5d3da5c8abaf" } ] } diff --git a/staging/src/k8s.io/sample-controller/Godeps/Godeps.json b/staging/src/k8s.io/sample-controller/Godeps/Godeps.json index 6e8d4212645..49a65d64252 100644 --- a/staging/src/k8s.io/sample-controller/Godeps/Godeps.json +++ b/staging/src/k8s.io/sample-controller/Godeps/Godeps.json @@ -900,7 +900,7 @@ }, { "ImportPath": "k8s.io/kube-openapi/pkg/util/proto", - "Rev": "a07b7bbb58e7fdc5144f8d7046331d29fc9ad3b3" + "Rev": "50ae88d24ede7b8bad68e23c805b5d3da5c8abaf" } ] } diff --git a/vendor/k8s.io/kube-openapi/pkg/aggregator/aggregator.go b/vendor/k8s.io/kube-openapi/pkg/aggregator/aggregator.go index aceaa463560..9fb16e6e9c4 100644 --- a/vendor/k8s.io/kube-openapi/pkg/aggregator/aggregator.go +++ b/vendor/k8s.io/kube-openapi/pkg/aggregator/aggregator.go @@ -58,8 +58,10 @@ func (s *referenceWalker) walkRef(ref spec.Ref) spec.Ref { // We do not support external references yet. if !s.alreadyVisited[refStr] && strings.HasPrefix(refStr, definitionPrefix) { s.alreadyVisited[refStr] = true - def := s.root.Definitions[refStr[len(definitionPrefix):]] + k := refStr[len(definitionPrefix):] + def := s.root.Definitions[k] s.walkSchema(&def) + s.root.Definitions[k] = def } return s.walkRefCallback(ref) } @@ -69,23 +71,26 @@ func (s *referenceWalker) walkSchema(schema *spec.Schema) { return } schema.Ref = s.walkRef(schema.Ref) - for _, v := range schema.Definitions { + for k, v := range schema.Definitions { s.walkSchema(&v) + schema.Definitions[k] = v } - for _, v := range schema.Properties { + for k, v := range schema.Properties { s.walkSchema(&v) + schema.Properties[k] = v } - for _, v := range schema.PatternProperties { + for k, v := range schema.PatternProperties { s.walkSchema(&v) + schema.PatternProperties[k] = v } - for _, v := range schema.AllOf { - s.walkSchema(&v) + for i, _ := range schema.AllOf { + s.walkSchema(&schema.AllOf[i]) } - for _, v := range schema.AnyOf { - s.walkSchema(&v) + for i, _ := range schema.AnyOf { + s.walkSchema(&schema.AnyOf[i]) } - for _, v := range schema.OneOf { - s.walkSchema(&v) + for i, _ := range schema.OneOf { + s.walkSchema(&schema.OneOf[i]) } if schema.Not != nil { s.walkSchema(schema.Not) @@ -100,8 +105,8 @@ func (s *referenceWalker) walkSchema(schema *spec.Schema) { if schema.Items.Schema != nil { s.walkSchema(schema.Items.Schema) } - for _, v := range schema.Items.Schemas { - s.walkSchema(&v) + for i, _ := range schema.Items.Schemas { + s.walkSchema(&schema.Items.Schemas[i]) } } } @@ -291,15 +296,29 @@ func mergeSpecs(dest, source *spec.Swagger, renameModelConflicts, ignorePathConf from, to string } renames := []Rename{} + + OUTERLOOP: for k, v := range source.Definitions { if usedNames[k] { v2, found := dest.Definitions[k] - // Reuse model iff they are exactly the same. + // Reuse model if they are exactly the same. if found && reflect.DeepEqual(v, v2) { continue } - i := 2 - newName := fmt.Sprintf("%s_v%d", k, i) + + // Reuse previously renamed model if one exists + var newName string + i := 1 + for found { + i++ + newName = fmt.Sprintf("%s_v%d", k, i) + v2, found = dest.Definitions[newName] + if found && reflect.DeepEqual(v, v2) { + renames = append(renames, Rename{from: k, to: newName}) + continue OUTERLOOP + } + } + _, foundInSource := source.Definitions[newName] for usedNames[newName] || foundInSource { i++ diff --git a/vendor/k8s.io/kube-openapi/pkg/generators/openapi.go b/vendor/k8s.io/kube-openapi/pkg/generators/openapi.go index d9b0980abb4..73e367b3559 100644 --- a/vendor/k8s.io/kube-openapi/pkg/generators/openapi.go +++ b/vendor/k8s.io/kube-openapi/pkg/generators/openapi.go @@ -634,6 +634,8 @@ func (g openAPITypeWriter) generateSliceProperty(t *types.Type) error { return fmt.Errorf("please add type %v to getOpenAPITypeFormat function", elemType) case types.Struct: g.generateReferenceProperty(elemType) + case types.Slice, types.Array: + g.generateSliceProperty(elemType) default: return fmt.Errorf("slice Element kind %v is not supported in %v", elemType.Kind, t) } diff --git a/vendor/k8s.io/kube-openapi/pkg/handler/BUILD b/vendor/k8s.io/kube-openapi/pkg/handler/BUILD index 3e51d0c7694..072a64ec310 100644 --- a/vendor/k8s.io/kube-openapi/pkg/handler/BUILD +++ b/vendor/k8s.io/kube-openapi/pkg/handler/BUILD @@ -6,6 +6,7 @@ go_library( importpath = "k8s.io/kube-openapi/pkg/handler", visibility = ["//visibility:public"], deps = [ + "//vendor/bitbucket.org/ww/goautoneg:go_default_library", "//vendor/github.com/NYTimes/gziphandler:go_default_library", "//vendor/github.com/emicklei/go-restful:go_default_library", "//vendor/github.com/go-openapi/spec:go_default_library", diff --git a/vendor/k8s.io/kube-openapi/pkg/handler/handler.go b/vendor/k8s.io/kube-openapi/pkg/handler/handler.go index 40f0fee3f1d..5a16cfcab40 100644 --- a/vendor/k8s.io/kube-openapi/pkg/handler/handler.go +++ b/vendor/k8s.io/kube-openapi/pkg/handler/handler.go @@ -22,18 +22,21 @@ import ( "crypto/sha512" "encoding/json" "fmt" - "gopkg.in/yaml.v2" "mime" "net/http" "strings" "sync" "time" + "bitbucket.org/ww/goautoneg" + + yaml "gopkg.in/yaml.v2" + "github.com/NYTimes/gziphandler" - "github.com/emicklei/go-restful" + restful "github.com/emicklei/go-restful" "github.com/go-openapi/spec" "github.com/golang/protobuf/proto" - "github.com/googleapis/gnostic/OpenAPIv2" + openapi_v2 "github.com/googleapis/gnostic/OpenAPIv2" "github.com/googleapis/gnostic/compiler" "k8s.io/kube-openapi/pkg/builder" @@ -77,6 +80,10 @@ func computeETag(data []byte) string { return fmt.Sprintf("\"%X\"", sha512.Sum512(data)) } +// NOTE: [DEPRECATION] We will announce deprecation for format-separated endpoints for OpenAPI spec, +// and switch to a single /openapi/v2 endpoint in Kubernetes 1.10. The design doc and deprecation process +// are tracked at: https://docs.google.com/document/d/19lEqE9lc4yHJ3WJAJxS_G7TcORIJXGHyq3wpwcH28nU. +// // BuildAndRegisterOpenAPIService builds the spec and registers a handler to provides access to it. // Use this method if your OpenAPI spec is static. If you want to update the spec, use BuildOpenAPISpec then RegisterOpenAPIService. func BuildAndRegisterOpenAPIService(servePath string, webServices []*restful.WebService, config *common.Config, handler common.PathHandler) (*OpenAPIService, error) { @@ -87,6 +94,10 @@ func BuildAndRegisterOpenAPIService(servePath string, webServices []*restful.Web return RegisterOpenAPIService(spec, servePath, handler) } +// NOTE: [DEPRECATION] We will announce deprecation for format-separated endpoints for OpenAPI spec, +// and switch to a single /openapi/v2 endpoint in Kubernetes 1.10. The design doc and deprecation process +// are tracked at: https://docs.google.com/document/d/19lEqE9lc4yHJ3WJAJxS_G7TcORIJXGHyq3wpwcH28nU. +// // RegisterOpenAPIService registers a handler to provides access to provided swagger spec. // Note: servePath should end with ".json" as the RegisterOpenAPIService assume it is serving a // json file and will also serve .pb and .gz files. @@ -202,3 +213,63 @@ func toGzip(data []byte) []byte { zw.Close() return buf.Bytes() } + +// RegisterOpenAPIVersionedService registers a handler to provides access to provided swagger spec. +func RegisterOpenAPIVersionedService(openapiSpec *spec.Swagger, servePath string, handler common.PathHandler) (*OpenAPIService, error) { + o := OpenAPIService{} + if err := o.UpdateSpec(openapiSpec); err != nil { + return nil, err + } + + accepted := []struct { + Type string + SubType string + GetDataAndETag func() ([]byte, string, time.Time) + }{ + {"application", "json", o.getSwaggerBytes}, + {"application", "com.github.proto-openapi.spec.v2@v1.0+protobuf", o.getSwaggerPbBytes}, + } + + handler.Handle(servePath, gziphandler.GzipHandler(http.HandlerFunc( + func(w http.ResponseWriter, r *http.Request) { + decipherableFormats := r.Header.Get("Accept") + if decipherableFormats == "" { + decipherableFormats = "*/*" + } + clauses := goautoneg.ParseAccept(decipherableFormats) + w.Header().Add("Vary", "Accept") + for _, clause := range clauses { + for _, accepts := range accepted { + if clause.Type != accepts.Type && clause.Type != "*" { + continue + } + if clause.SubType != accepts.SubType && clause.SubType != "*" { + continue + } + + // serve the first matching media type in the sorted clause list + data, etag, lastModified := accepts.GetDataAndETag() + w.Header().Set("Etag", etag) + // ServeContent will take care of caching using eTag. + http.ServeContent(w, r, servePath, lastModified, bytes.NewReader(data)) + return + } + } + // Return 406 for not acceptable format + w.WriteHeader(406) + return + }), + )) + + return &o, nil +} + +// BuildAndRegisterOpenAPIVersionedService builds the spec and registers a handler to provides access to it. +// Use this method if your OpenAPI spec is static. If you want to update the spec, use BuildOpenAPISpec then RegisterOpenAPIVersionedService. +func BuildAndRegisterOpenAPIVersionedService(servePath string, webServices []*restful.WebService, config *common.Config, handler common.PathHandler) (*OpenAPIService, error) { + spec, err := builder.BuildOpenAPISpec(webServices, config) + if err != nil { + return nil, err + } + return RegisterOpenAPIVersionedService(spec, servePath, handler) +}