Merge pull request #64596 from apelisse/openapi-some-cleanup

Automatic merge from submit-queue (batch tested with PRs 64613, 64596, 64573, 64154, 64639). If you want to cherry-pick this change to another branch, please follow the instructions <a href="https://github.com/kubernetes/community/blob/master/contributors/devel/cherry-picks.md">here</a>.

Openapi some cleanup

Clean-up some OpenAPI code, mostly test related (there are two implementations of "Fake").
This is going for master, but I'll probably also cherry-pick/create a similar PR for feature-serverside-apply branch since we'll need that to move some code around.

**What this PR does / why we need it**:

**Which issue(s) this PR fixes** *(optional, in `fixes #<issue number>(, fixes #<issue_number>, ...)` format, will close the issue(s) when PR gets merged)*:
Fixes #

**Special notes for your reviewer**:

**Release note**:

```release-note
NONE
```

Kubernetes-commit: c3bb41ad4b147f6159dd7542ffd2772d7042e2d8
This commit is contained in:
Kubernetes Publisher
2018-06-02 06:30:13 -07:00
3 changed files with 46 additions and 32 deletions
+1 -1
View File
@@ -1076,7 +1076,7 @@
}, },
{ {
"ImportPath": "k8s.io/kube-openapi/pkg/util/proto", "ImportPath": "k8s.io/kube-openapi/pkg/util/proto",
"Rev": "86e28c192d2743f0232b9bc5f0a531568ef9f2a5" "Rev": "8a9b82f00b3a86eac24681da3f9fe6c34c01cea2"
} }
] ]
} }
+44 -30
View File
@@ -21,8 +21,8 @@ import (
"sort" "sort"
"strings" "strings"
openapi_v2 "github.com/googleapis/gnostic/OpenAPIv2" "github.com/googleapis/gnostic/OpenAPIv2"
yaml "gopkg.in/yaml.v2" "gopkg.in/yaml.v2"
) )
func newSchemaError(path *Path, format string, a ...interface{}) error { func newSchemaError(path *Path, format string, a ...interface{}) error {
@@ -126,12 +126,17 @@ func (d *Definitions) parseMap(s *openapi_v2.Schema, path *Path) (Schema, error)
if len(s.GetType().GetValue()) != 0 && s.GetType().GetValue()[0] != object { if len(s.GetType().GetValue()) != 0 && s.GetType().GetValue()[0] != object {
return nil, newSchemaError(path, "invalid object type") return nil, newSchemaError(path, "invalid object type")
} }
var sub Schema
if s.GetAdditionalProperties().GetSchema() == nil { if s.GetAdditionalProperties().GetSchema() == nil {
return nil, newSchemaError(path, "invalid object doesn't have additional properties") sub = &Arbitrary{
} BaseSchema: d.parseBaseSchema(s, path),
sub, err := d.ParseSchema(s.GetAdditionalProperties().GetSchema(), path) }
if err != nil { } else {
return nil, err var err error
sub, err = d.ParseSchema(s.GetAdditionalProperties().GetSchema(), path)
if err != nil {
return nil, err
}
} }
return &Map{ return &Map{
BaseSchema: d.parseBaseSchema(s, path), BaseSchema: d.parseBaseSchema(s, path),
@@ -148,12 +153,10 @@ func (d *Definitions) parsePrimitive(s *openapi_v2.Schema, path *Path) (Schema,
t = s.GetType().GetValue()[0] t = s.GetType().GetValue()[0]
} }
switch t { switch t {
case String: case String: // do nothing
case Number: case Number: // do nothing
case Integer: case Integer: // do nothing
case Boolean: case Boolean: // do nothing
case "": // Some models are completely empty, and can be safely ignored.
// Do nothing
default: default:
return nil, newSchemaError(path, "Unknown primitive type: %q", t) return nil, newSchemaError(path, "Unknown primitive type: %q", t)
} }
@@ -219,27 +222,38 @@ func (d *Definitions) parseArbitrary(s *openapi_v2.Schema, path *Path) (Schema,
// ParseSchema creates a walkable Schema from an openapi schema. While // ParseSchema creates a walkable Schema from an openapi schema. While
// this function is public, it doesn't leak through the interface. // this function is public, it doesn't leak through the interface.
func (d *Definitions) ParseSchema(s *openapi_v2.Schema, path *Path) (Schema, error) { func (d *Definitions) ParseSchema(s *openapi_v2.Schema, path *Path) (Schema, error) {
objectTypes := s.GetType().GetValue()
if len(objectTypes) == 1 {
t := objectTypes[0]
switch t {
case object:
return d.parseMap(s, path)
case array:
return d.parseArray(s, path)
}
}
if s.GetXRef() != "" { if s.GetXRef() != "" {
return d.parseReference(s, path) return d.parseReference(s, path)
} }
if s.GetProperties() != nil { objectTypes := s.GetType().GetValue()
return d.parseKind(s, path) switch len(objectTypes) {
case 0:
// in the OpenAPI schema served by older k8s versions, object definitions created from structs did not include
// the type:object property (they only included the "properties" property), so we need to handle this case
if s.GetProperties() != nil {
return d.parseKind(s, path)
} else {
// Definition has no type and no properties. Treat it as an arbitrary value
// TODO: what if it has additionalProperties or patternProperties?
return d.parseArbitrary(s, path)
}
case 1:
t := objectTypes[0]
switch t {
case object:
if s.GetProperties() != nil {
return d.parseKind(s, path)
} else {
return d.parseMap(s, path)
}
case array:
return d.parseArray(s, path)
}
return d.parsePrimitive(s, path)
default:
// the OpenAPI generator never generates (nor it ever did in the past) OpenAPI type definitions with multiple types
return nil, newSchemaError(path, "definitions with multiple types aren't supported")
} }
if len(objectTypes) == 0 || (len(objectTypes) == 1 && objectTypes[0] == "") {
return d.parseArbitrary(s, path)
}
return d.parsePrimitive(s, path)
} }
// LookupModel is public through the interface of Models. It // LookupModel is public through the interface of Models. It
+1 -1
View File
@@ -59,7 +59,7 @@ type SchemaVisitor interface {
} }
// SchemaVisitorArbitrary is an additional visitor interface which handles // SchemaVisitorArbitrary is an additional visitor interface which handles
// arbitrary types. For backwards compatability, it's a separate interface // arbitrary types. For backwards compatibility, it's a separate interface
// which is checked for at runtime. // which is checked for at runtime.
type SchemaVisitorArbitrary interface { type SchemaVisitorArbitrary interface {
SchemaVisitor SchemaVisitor