4
vendor/k8s.io/kube-openapi/pkg/builder/openapi.go
generated
vendored
4
vendor/k8s.io/kube-openapi/pkg/builder/openapi.go
generated
vendored
@@ -369,7 +369,7 @@ func (o *openAPI) findCommonParameters(routes []restful.Route) (map[interface{}]
|
||||
}
|
||||
|
||||
func (o *openAPI) toSchema(name string) (_ *spec.Schema, err error) {
|
||||
if openAPIType, openAPIFormat := common.GetOpenAPITypeFormat(name); openAPIType != "" {
|
||||
if openAPIType, openAPIFormat := common.OpenAPITypeFormat(name); openAPIType != "" {
|
||||
return &spec.Schema{
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Type: []string{openAPIType},
|
||||
@@ -423,7 +423,7 @@ func (o *openAPI) buildParameter(restParam restful.ParameterData, bodySample int
|
||||
default:
|
||||
return ret, fmt.Errorf("unknown restful operation kind : %v", restParam.Kind)
|
||||
}
|
||||
openAPIType, openAPIFormat := common.GetOpenAPITypeFormat(restParam.DataType)
|
||||
openAPIType, openAPIFormat := common.OpenAPITypeFormat(restParam.DataType)
|
||||
if openAPIType == "" {
|
||||
return ret, fmt.Errorf("non-body Restful parameter type should be a simple type, but got : %v", restParam.DataType)
|
||||
}
|
||||
|
||||
66
vendor/k8s.io/kube-openapi/pkg/common/common.go
generated
vendored
66
vendor/k8s.io/kube-openapi/pkg/common/common.go
generated
vendored
@@ -26,7 +26,7 @@ import (
|
||||
|
||||
const (
|
||||
// TODO: Make this configurable.
|
||||
ExtensionPrefix = "x-kubernetes-"
|
||||
ExtensionPrefix = "x-kubernetes-"
|
||||
ExtensionV2Schema = ExtensionPrefix + "v2-schema"
|
||||
)
|
||||
|
||||
@@ -105,28 +105,34 @@ type Config struct {
|
||||
DefaultSecurity []map[string][]string
|
||||
}
|
||||
|
||||
var schemaTypeFormatMap = map[string][]string{
|
||||
"uint": {"integer", "int32"},
|
||||
"uint8": {"integer", "byte"},
|
||||
"uint16": {"integer", "int32"},
|
||||
"uint32": {"integer", "int64"},
|
||||
"uint64": {"integer", "int64"},
|
||||
"int": {"integer", "int32"},
|
||||
"int8": {"integer", "byte"},
|
||||
"int16": {"integer", "int32"},
|
||||
"int32": {"integer", "int32"},
|
||||
"int64": {"integer", "int64"},
|
||||
"byte": {"integer", "byte"},
|
||||
"float64": {"number", "double"},
|
||||
"float32": {"number", "float"},
|
||||
"bool": {"boolean", ""},
|
||||
"time.Time": {"string", "date-time"},
|
||||
"string": {"string", ""},
|
||||
"integer": {"integer", ""},
|
||||
"number": {"number", ""},
|
||||
"boolean": {"boolean", ""},
|
||||
"[]byte": {"string", "byte"}, // base64 encoded characters
|
||||
"interface{}": {"object", ""},
|
||||
type typeInfo struct {
|
||||
name string
|
||||
format string
|
||||
zero interface{}
|
||||
}
|
||||
|
||||
var schemaTypeFormatMap = map[string]typeInfo{
|
||||
"uint": {"integer", "int32", 0.},
|
||||
"uint8": {"integer", "byte", 0.},
|
||||
"uint16": {"integer", "int32", 0.},
|
||||
"uint32": {"integer", "int64", 0.},
|
||||
"uint64": {"integer", "int64", 0.},
|
||||
"int": {"integer", "int32", 0.},
|
||||
"int8": {"integer", "byte", 0.},
|
||||
"int16": {"integer", "int32", 0.},
|
||||
"int32": {"integer", "int32", 0.},
|
||||
"int64": {"integer", "int64", 0.},
|
||||
"byte": {"integer", "byte", 0},
|
||||
"float64": {"number", "double", 0.},
|
||||
"float32": {"number", "float", 0.},
|
||||
"bool": {"boolean", "", false},
|
||||
"time.Time": {"string", "date-time", ""},
|
||||
"string": {"string", "", ""},
|
||||
"integer": {"integer", "", 0.},
|
||||
"number": {"number", "", 0.},
|
||||
"boolean": {"boolean", "", false},
|
||||
"[]byte": {"string", "byte", ""}, // base64 encoded characters
|
||||
"interface{}": {"object", "", interface{}(nil)},
|
||||
}
|
||||
|
||||
// This function is a reference for converting go (or any custom type) to a simple open API type,format pair. There are
|
||||
@@ -168,12 +174,22 @@ var schemaTypeFormatMap = map[string][]string{
|
||||
// }
|
||||
// }
|
||||
//
|
||||
func GetOpenAPITypeFormat(typeName string) (string, string) {
|
||||
func OpenAPITypeFormat(typeName string) (string, string) {
|
||||
mapped, ok := schemaTypeFormatMap[typeName]
|
||||
if !ok {
|
||||
return "", ""
|
||||
}
|
||||
return mapped[0], mapped[1]
|
||||
return mapped.name, mapped.format
|
||||
}
|
||||
|
||||
// Returns the zero-value for the given type along with true if the type
|
||||
// could be found.
|
||||
func OpenAPIZeroValue(typeName string) (interface{}, bool) {
|
||||
mapped, ok := schemaTypeFormatMap[typeName]
|
||||
if !ok {
|
||||
return nil, false
|
||||
}
|
||||
return mapped.zero, true
|
||||
}
|
||||
|
||||
func EscapeJsonPointer(p string) string {
|
||||
|
||||
2
vendor/k8s.io/kube-openapi/pkg/generators/api_linter.go
generated
vendored
2
vendor/k8s.io/kube-openapi/pkg/generators/api_linter.go
generated
vendored
@@ -28,7 +28,7 @@ import (
|
||||
|
||||
"k8s.io/gengo/generator"
|
||||
"k8s.io/gengo/types"
|
||||
"k8s.io/klog"
|
||||
"k8s.io/klog/v2"
|
||||
)
|
||||
|
||||
const apiViolationFileType = "api-violation"
|
||||
|
||||
2
vendor/k8s.io/kube-openapi/pkg/generators/config.go
generated
vendored
2
vendor/k8s.io/kube-openapi/pkg/generators/config.go
generated
vendored
@@ -24,7 +24,7 @@ import (
|
||||
"k8s.io/gengo/generator"
|
||||
"k8s.io/gengo/namer"
|
||||
"k8s.io/gengo/types"
|
||||
"k8s.io/klog"
|
||||
"k8s.io/klog/v2"
|
||||
|
||||
generatorargs "k8s.io/kube-openapi/cmd/openapi-gen/args"
|
||||
)
|
||||
|
||||
10
vendor/k8s.io/kube-openapi/pkg/generators/extension.go
generated
vendored
10
vendor/k8s.io/kube-openapi/pkg/generators/extension.go
generated
vendored
@@ -56,6 +56,16 @@ var tagToExtension = map[string]extensionAttributes{
|
||||
kind: types.Slice,
|
||||
allowedValues: sets.NewString("atomic", "set", "map"),
|
||||
},
|
||||
"mapType": {
|
||||
xName: "x-kubernetes-map-type",
|
||||
kind: types.Map,
|
||||
allowedValues: sets.NewString("atomic", "granular"),
|
||||
},
|
||||
"structType": {
|
||||
xName: "x-kubernetes-map-type",
|
||||
kind: types.Struct,
|
||||
allowedValues: sets.NewString("atomic", "granular"),
|
||||
},
|
||||
}
|
||||
|
||||
// Extension encapsulates information necessary to generate an OpenAPI extension.
|
||||
|
||||
97
vendor/k8s.io/kube-openapi/pkg/generators/openapi.go
generated
vendored
97
vendor/k8s.io/kube-openapi/pkg/generators/openapi.go
generated
vendored
@@ -18,6 +18,7 @@ package generators
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"path/filepath"
|
||||
@@ -30,12 +31,13 @@ import (
|
||||
"k8s.io/gengo/types"
|
||||
openapi "k8s.io/kube-openapi/pkg/common"
|
||||
|
||||
"k8s.io/klog"
|
||||
"k8s.io/klog/v2"
|
||||
)
|
||||
|
||||
// This is the comment tag that carries parameters for open API generation.
|
||||
const tagName = "k8s:openapi-gen"
|
||||
const tagOptional = "optional"
|
||||
const tagDefault = "default"
|
||||
|
||||
// Known values for the tag.
|
||||
const (
|
||||
@@ -282,6 +284,9 @@ func typeShortName(t *types.Type) string {
|
||||
|
||||
func (g openAPITypeWriter) generateMembers(t *types.Type, required []string) ([]string, error) {
|
||||
var err error
|
||||
for t.Kind == types.Pointer { // fast-forward to effective type containing members
|
||||
t = t.Elem
|
||||
}
|
||||
for _, m := range t.Members {
|
||||
if hasOpenAPITagValue(m.CommentLines, tagValueFalse) {
|
||||
continue
|
||||
@@ -411,7 +416,7 @@ func (g openAPITypeWriter) generate(t *types.Type) error {
|
||||
deps := []string{}
|
||||
for _, k := range keys {
|
||||
v := g.refTypes[k]
|
||||
if t, _ := openapi.GetOpenAPITypeFormat(v.String()); t != "" {
|
||||
if t, _ := openapi.OpenAPITypeFormat(v.String()); t != "" {
|
||||
// This is a known type, we do not need a reference to it
|
||||
// Will eliminate special case of time.Time
|
||||
continue
|
||||
@@ -510,6 +515,60 @@ func (g openAPITypeWriter) validatePatchTags(m *types.Member, parent *types.Type
|
||||
return nil
|
||||
}
|
||||
|
||||
func defaultFromComments(comments []string) (interface{}, error) {
|
||||
tag, err := getSingleTagsValue(comments, tagDefault)
|
||||
if tag == "" {
|
||||
return nil, err
|
||||
}
|
||||
var i interface{}
|
||||
if err := json.Unmarshal([]byte(tag), &i); err != nil {
|
||||
return nil, fmt.Errorf("failed to unmarshal default: %v", err)
|
||||
}
|
||||
return i, nil
|
||||
}
|
||||
|
||||
func mustEnforceDefault(t *types.Type, omitEmpty bool) (interface{}, error) {
|
||||
switch t.Kind {
|
||||
case types.Pointer, types.Map, types.Slice, types.Array, types.Interface:
|
||||
return nil, nil
|
||||
case types.Struct:
|
||||
return map[string]interface{}{}, nil
|
||||
case types.Builtin:
|
||||
if !omitEmpty {
|
||||
if zero, ok := openapi.OpenAPIZeroValue(t.String()); ok {
|
||||
return zero, nil
|
||||
} else {
|
||||
return nil, fmt.Errorf("please add type %v to getOpenAPITypeFormat function", t)
|
||||
}
|
||||
}
|
||||
return nil, nil
|
||||
default:
|
||||
return nil, fmt.Errorf("not sure how to enforce default for %v", t.Kind)
|
||||
}
|
||||
}
|
||||
|
||||
func (g openAPITypeWriter) generateDefault(comments []string, t *types.Type, omitEmpty bool) error {
|
||||
t = resolveAliasType(t)
|
||||
def, err := defaultFromComments(comments)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if enforced, err := mustEnforceDefault(t, omitEmpty); err != nil {
|
||||
return err
|
||||
} else if enforced != nil {
|
||||
if def == nil {
|
||||
def = enforced
|
||||
} else if !reflect.DeepEqual(def, enforced) {
|
||||
enforcedJson, _ := json.Marshal(enforced)
|
||||
return fmt.Errorf("invalid default value (%#v) for non-pointer/non-omitempty. If specified, must be: %v", def, string(enforcedJson))
|
||||
}
|
||||
}
|
||||
if def != nil {
|
||||
g.Do("Default: $.$,\n", fmt.Sprintf("%#v", def))
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (g openAPITypeWriter) generateDescription(CommentLines []string) {
|
||||
var buffer bytes.Buffer
|
||||
delPrevChar := func() {
|
||||
@@ -534,7 +593,7 @@ func (g openAPITypeWriter) generateDescription(CommentLines []string) {
|
||||
default:
|
||||
if strings.HasPrefix(line, " ") || strings.HasPrefix(line, "\t") {
|
||||
delPrevChar()
|
||||
line = "\n" + line + "\n" // Replace it with newline. This is useful when we have a line with: "Example:\n\tJSON-someting..."
|
||||
line = "\n" + line + "\n" // Replace it with newline. This is useful when we have a line with: "Example:\n\tJSON-something..."
|
||||
} else {
|
||||
line += " "
|
||||
}
|
||||
@@ -573,9 +632,13 @@ func (g openAPITypeWriter) generateProperty(m *types.Member, parent *types.Type)
|
||||
g.Do("},\n},\n", nil)
|
||||
return nil
|
||||
}
|
||||
omitEmpty := strings.Contains(reflect.StructTag(m.Tags).Get("json"), "omitempty")
|
||||
if err := g.generateDefault(m.CommentLines, m.Type, omitEmpty); err != nil {
|
||||
return fmt.Errorf("failed to generate default in %v: %v: %v", parent, m.Name, err)
|
||||
}
|
||||
t := resolveAliasAndPtrType(m.Type)
|
||||
// If we can get a openAPI type and format for this type, we consider it to be simple property
|
||||
typeString, format := openapi.GetOpenAPITypeFormat(t.String())
|
||||
typeString, format := openapi.OpenAPITypeFormat(t.String())
|
||||
if typeString != "" {
|
||||
g.generateSimpleProperty(typeString, format)
|
||||
g.Do("},\n},\n", nil)
|
||||
@@ -586,11 +649,11 @@ func (g openAPITypeWriter) generateProperty(m *types.Member, parent *types.Type)
|
||||
return fmt.Errorf("please add type %v to getOpenAPITypeFormat function", t)
|
||||
case types.Map:
|
||||
if err := g.generateMapProperty(t); err != nil {
|
||||
return err
|
||||
return fmt.Errorf("failed to generate map property in %v: %v: %v", parent, m.Name, err)
|
||||
}
|
||||
case types.Slice, types.Array:
|
||||
if err := g.generateSliceProperty(t); err != nil {
|
||||
return err
|
||||
return fmt.Errorf("failed to generate slice property in %v: %v: %v", parent, m.Name, err)
|
||||
}
|
||||
case types.Struct, types.Interface:
|
||||
g.generateReferenceProperty(t)
|
||||
@@ -611,6 +674,17 @@ func (g openAPITypeWriter) generateReferenceProperty(t *types.Type) {
|
||||
g.Do("Ref: ref(\"$.$\"),\n", t.Name.String())
|
||||
}
|
||||
|
||||
func resolveAliasType(t *types.Type) *types.Type {
|
||||
var prev *types.Type
|
||||
for prev != t {
|
||||
prev = t
|
||||
if t.Kind == types.Alias {
|
||||
t = t.Underlying
|
||||
}
|
||||
}
|
||||
return t
|
||||
}
|
||||
|
||||
func resolveAliasAndPtrType(t *types.Type) *types.Type {
|
||||
var prev *types.Type
|
||||
for prev != t {
|
||||
@@ -633,9 +707,13 @@ func (g openAPITypeWriter) generateMapProperty(t *types.Type) error {
|
||||
if keyType.Name.Name != "string" {
|
||||
return fmt.Errorf("map with non-string keys are not supported by OpenAPI in %v", t)
|
||||
}
|
||||
|
||||
g.Do("Type: []string{\"object\"},\n", nil)
|
||||
g.Do("AdditionalProperties: &spec.SchemaOrBool{\nAllows: true,\nSchema: &spec.Schema{\nSchemaProps: spec.SchemaProps{\n", nil)
|
||||
typeString, format := openapi.GetOpenAPITypeFormat(elemType.String())
|
||||
if err := g.generateDefault(t.Elem.CommentLines, t.Elem, false); err != nil {
|
||||
return err
|
||||
}
|
||||
typeString, format := openapi.OpenAPITypeFormat(elemType.String())
|
||||
if typeString != "" {
|
||||
g.generateSimpleProperty(typeString, format)
|
||||
g.Do("},\n},\n},\n", nil)
|
||||
@@ -665,7 +743,10 @@ func (g openAPITypeWriter) generateSliceProperty(t *types.Type) error {
|
||||
elemType := resolveAliasAndPtrType(t.Elem)
|
||||
g.Do("Type: []string{\"array\"},\n", nil)
|
||||
g.Do("Items: &spec.SchemaOrArray{\nSchema: &spec.Schema{\nSchemaProps: spec.SchemaProps{\n", nil)
|
||||
typeString, format := openapi.GetOpenAPITypeFormat(elemType.String())
|
||||
if err := g.generateDefault(t.Elem.CommentLines, t.Elem, false); err != nil {
|
||||
return err
|
||||
}
|
||||
typeString, format := openapi.OpenAPITypeFormat(elemType.String())
|
||||
if typeString != "" {
|
||||
g.generateSimpleProperty(typeString, format)
|
||||
g.Do("},\n},\n},\n", nil)
|
||||
|
||||
21
vendor/k8s.io/kube-openapi/pkg/generators/rules/idl_tag.go
generated
vendored
21
vendor/k8s.io/kube-openapi/pkg/generators/rules/idl_tag.go
generated
vendored
@@ -24,7 +24,16 @@ func (l *ListTypeMissing) Validate(t *types.Type) ([]string, error) {
|
||||
switch t.Kind {
|
||||
case types.Struct:
|
||||
for _, m := range t.Members {
|
||||
if m.Type.Kind == types.Slice && types.ExtractCommentTags("+", m.CommentLines)[ListTypeIDLTag] == nil {
|
||||
hasListType := types.ExtractCommentTags("+", m.CommentLines)[ListTypeIDLTag] != nil
|
||||
|
||||
if m.Name == "Items" && m.Type.Kind == types.Slice && hasNamedMember(t, "ListMeta") {
|
||||
if hasListType {
|
||||
fields = append(fields, m.Name)
|
||||
}
|
||||
continue
|
||||
}
|
||||
|
||||
if m.Type.Kind == types.Slice && !hasListType {
|
||||
fields = append(fields, m.Name)
|
||||
continue
|
||||
}
|
||||
@@ -32,5 +41,13 @@ func (l *ListTypeMissing) Validate(t *types.Type) ([]string, error) {
|
||||
}
|
||||
|
||||
return fields, nil
|
||||
|
||||
}
|
||||
|
||||
func hasNamedMember(t *types.Type, name string) bool {
|
||||
for _, m := range t.Members {
|
||||
if m.Name == name {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
2
vendor/k8s.io/kube-openapi/pkg/generators/rules/names_match.go
generated
vendored
2
vendor/k8s.io/kube-openapi/pkg/generators/rules/names_match.go
generated
vendored
@@ -155,7 +155,7 @@ func namesMatch(goName, jsonName string) bool {
|
||||
return true
|
||||
}
|
||||
|
||||
// isCaptical returns true if one character is capital
|
||||
// isCapital returns true if one character is capital
|
||||
func isCapital(b byte) bool {
|
||||
return b >= 'A' && b <= 'Z'
|
||||
}
|
||||
|
||||
208
vendor/k8s.io/kube-openapi/pkg/handler/default_pruning.go
generated
vendored
Normal file
208
vendor/k8s.io/kube-openapi/pkg/handler/default_pruning.go
generated
vendored
Normal file
@@ -0,0 +1,208 @@
|
||||
/*
|
||||
Copyright 2020 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.
|
||||
*/
|
||||
|
||||
package handler
|
||||
|
||||
import "github.com/go-openapi/spec"
|
||||
|
||||
// PruneDefaults remove all the defaults recursively from all the
|
||||
// schemas in the definitions, and does not modify the definitions in
|
||||
// place.
|
||||
func PruneDefaults(definitions spec.Definitions) spec.Definitions {
|
||||
definitionsCloned := false
|
||||
for k, v := range definitions {
|
||||
if s := PruneDefaultsSchema(&v); s != &v {
|
||||
if !definitionsCloned {
|
||||
definitionsCloned = true
|
||||
orig := definitions
|
||||
definitions = make(spec.Definitions, len(orig))
|
||||
for k2, v2 := range orig {
|
||||
definitions[k2] = v2
|
||||
}
|
||||
}
|
||||
definitions[k] = *s
|
||||
}
|
||||
}
|
||||
return definitions
|
||||
}
|
||||
|
||||
// PruneDefaultsSchema remove all the defaults recursively from the
|
||||
// schema in place.
|
||||
func PruneDefaultsSchema(schema *spec.Schema) *spec.Schema {
|
||||
if schema == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
orig := schema
|
||||
clone := func() {
|
||||
if orig == schema {
|
||||
schema = &spec.Schema{}
|
||||
*schema = *orig
|
||||
}
|
||||
}
|
||||
|
||||
if schema.Default != nil {
|
||||
clone()
|
||||
schema.Default = nil
|
||||
}
|
||||
|
||||
definitionsCloned := false
|
||||
for k, v := range schema.Definitions {
|
||||
if s := PruneDefaultsSchema(&v); s != &v {
|
||||
if !definitionsCloned {
|
||||
definitionsCloned = true
|
||||
clone()
|
||||
schema.Definitions = make(spec.Definitions, len(orig.Definitions))
|
||||
for k2, v2 := range orig.Definitions {
|
||||
schema.Definitions[k2] = v2
|
||||
}
|
||||
}
|
||||
schema.Definitions[k] = *s
|
||||
}
|
||||
}
|
||||
|
||||
propertiesCloned := false
|
||||
for k, v := range schema.Properties {
|
||||
if s := PruneDefaultsSchema(&v); s != &v {
|
||||
if !propertiesCloned {
|
||||
propertiesCloned = true
|
||||
clone()
|
||||
schema.Properties = make(map[string]spec.Schema, len(orig.Properties))
|
||||
for k2, v2 := range orig.Properties {
|
||||
schema.Properties[k2] = v2
|
||||
}
|
||||
}
|
||||
schema.Properties[k] = *s
|
||||
}
|
||||
}
|
||||
|
||||
patternPropertiesCloned := false
|
||||
for k, v := range schema.PatternProperties {
|
||||
if s := PruneDefaultsSchema(&v); s != &v {
|
||||
if !patternPropertiesCloned {
|
||||
patternPropertiesCloned = true
|
||||
clone()
|
||||
schema.PatternProperties = make(map[string]spec.Schema, len(orig.PatternProperties))
|
||||
for k2, v2 := range orig.PatternProperties {
|
||||
schema.PatternProperties[k2] = v2
|
||||
}
|
||||
}
|
||||
schema.PatternProperties[k] = *s
|
||||
}
|
||||
}
|
||||
|
||||
dependenciesCloned := false
|
||||
for k, v := range schema.Dependencies {
|
||||
if s := PruneDefaultsSchema(v.Schema); s != v.Schema {
|
||||
if !dependenciesCloned {
|
||||
dependenciesCloned = true
|
||||
clone()
|
||||
schema.Dependencies = make(spec.Dependencies, len(orig.Dependencies))
|
||||
for k2, v2 := range orig.Dependencies {
|
||||
schema.Dependencies[k2] = v2
|
||||
}
|
||||
}
|
||||
v.Schema = s
|
||||
schema.Dependencies[k] = v
|
||||
}
|
||||
}
|
||||
|
||||
allOfCloned := false
|
||||
for i := range schema.AllOf {
|
||||
if s := PruneDefaultsSchema(&schema.AllOf[i]); s != &schema.AllOf[i] {
|
||||
if !allOfCloned {
|
||||
allOfCloned = true
|
||||
clone()
|
||||
schema.AllOf = make([]spec.Schema, len(orig.AllOf))
|
||||
copy(schema.AllOf, orig.AllOf)
|
||||
}
|
||||
schema.AllOf[i] = *s
|
||||
}
|
||||
}
|
||||
|
||||
anyOfCloned := false
|
||||
for i := range schema.AnyOf {
|
||||
if s := PruneDefaultsSchema(&schema.AnyOf[i]); s != &schema.AnyOf[i] {
|
||||
if !anyOfCloned {
|
||||
anyOfCloned = true
|
||||
clone()
|
||||
schema.AnyOf = make([]spec.Schema, len(orig.AnyOf))
|
||||
copy(schema.AnyOf, orig.AnyOf)
|
||||
}
|
||||
schema.AnyOf[i] = *s
|
||||
}
|
||||
}
|
||||
|
||||
oneOfCloned := false
|
||||
for i := range schema.OneOf {
|
||||
if s := PruneDefaultsSchema(&schema.OneOf[i]); s != &schema.OneOf[i] {
|
||||
if !oneOfCloned {
|
||||
oneOfCloned = true
|
||||
clone()
|
||||
schema.OneOf = make([]spec.Schema, len(orig.OneOf))
|
||||
copy(schema.OneOf, orig.OneOf)
|
||||
}
|
||||
schema.OneOf[i] = *s
|
||||
}
|
||||
}
|
||||
|
||||
if schema.Not != nil {
|
||||
if s := PruneDefaultsSchema(schema.Not); s != schema.Not {
|
||||
clone()
|
||||
schema.Not = s
|
||||
}
|
||||
}
|
||||
|
||||
if schema.AdditionalProperties != nil && schema.AdditionalProperties.Schema != nil {
|
||||
if s := PruneDefaultsSchema(schema.AdditionalProperties.Schema); s != schema.AdditionalProperties.Schema {
|
||||
clone()
|
||||
schema.AdditionalProperties = &spec.SchemaOrBool{Schema: s, Allows: schema.AdditionalProperties.Allows}
|
||||
}
|
||||
}
|
||||
|
||||
if schema.AdditionalItems != nil && schema.AdditionalItems.Schema != nil {
|
||||
if s := PruneDefaultsSchema(schema.AdditionalItems.Schema); s != schema.AdditionalItems.Schema {
|
||||
clone()
|
||||
schema.AdditionalItems = &spec.SchemaOrBool{Schema: s, Allows: schema.AdditionalItems.Allows}
|
||||
}
|
||||
}
|
||||
|
||||
if schema.Items != nil {
|
||||
if schema.Items.Schema != nil {
|
||||
if s := PruneDefaultsSchema(schema.Items.Schema); s != schema.Items.Schema {
|
||||
clone()
|
||||
schema.Items = &spec.SchemaOrArray{Schema: s}
|
||||
}
|
||||
} else {
|
||||
itemsCloned := false
|
||||
for i := range schema.Items.Schemas {
|
||||
if s := PruneDefaultsSchema(&schema.Items.Schemas[i]); s != &schema.Items.Schemas[i] {
|
||||
if !itemsCloned {
|
||||
clone()
|
||||
schema.Items = &spec.SchemaOrArray{
|
||||
Schemas: make([]spec.Schema, len(orig.Items.Schemas)),
|
||||
}
|
||||
itemsCloned = true
|
||||
copy(schema.Items.Schemas, orig.Items.Schemas)
|
||||
}
|
||||
schema.Items.Schemas[i] = *s
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return schema
|
||||
}
|
||||
4
vendor/k8s.io/kube-openapi/pkg/handler/handler.go
generated
vendored
4
vendor/k8s.io/kube-openapi/pkg/handler/handler.go
generated
vendored
@@ -30,9 +30,9 @@ import (
|
||||
"github.com/emicklei/go-restful"
|
||||
"github.com/go-openapi/spec"
|
||||
"github.com/golang/protobuf/proto"
|
||||
"github.com/googleapis/gnostic/OpenAPIv2"
|
||||
"github.com/googleapis/gnostic/compiler"
|
||||
"github.com/json-iterator/go"
|
||||
openapi_v2 "github.com/googleapis/gnostic/openapiv2"
|
||||
jsoniter "github.com/json-iterator/go"
|
||||
"github.com/munnerz/goautoneg"
|
||||
"gopkg.in/yaml.v2"
|
||||
|
||||
|
||||
82
vendor/k8s.io/kube-openapi/pkg/schemaconv/smd.go
generated
vendored
82
vendor/k8s.io/kube-openapi/pkg/schemaconv/smd.go
generated
vendored
@@ -24,7 +24,11 @@ import (
|
||||
"strings"
|
||||
|
||||
"k8s.io/kube-openapi/pkg/util/proto"
|
||||
"sigs.k8s.io/structured-merge-diff/v3/schema"
|
||||
"sigs.k8s.io/structured-merge-diff/v4/schema"
|
||||
)
|
||||
|
||||
const (
|
||||
quantityResource = "io.k8s.apimachinery.pkg.api.resource.Quantity"
|
||||
)
|
||||
|
||||
// ToSchema converts openapi definitions into a schema suitable for structured
|
||||
@@ -263,7 +267,7 @@ func makeUnion(extensions map[string]interface{}) (schema.Union, error) {
|
||||
return schema.Union{}, fmt.Errorf(`"fields-to-discriminateBy"/%v: value must be a string, got: %#v`, field, value)
|
||||
}
|
||||
union.Fields = append(union.Fields, schema.UnionField{
|
||||
FieldName: field,
|
||||
FieldName: field,
|
||||
DiscriminatorValue: discriminated,
|
||||
})
|
||||
|
||||
@@ -293,8 +297,9 @@ func (c *convert) VisitKind(k *proto.Kind) {
|
||||
member := k.Fields[name]
|
||||
tr := c.makeRef(member, preserveUnknownFields)
|
||||
a.Map.Fields = append(a.Map.Fields, schema.StructField{
|
||||
Name: name,
|
||||
Type: tr,
|
||||
Name: name,
|
||||
Type: tr,
|
||||
Default: member.GetDefault(),
|
||||
})
|
||||
}
|
||||
|
||||
@@ -312,6 +317,18 @@ func (c *convert) VisitKind(k *proto.Kind) {
|
||||
NamedType: &deducedName,
|
||||
}
|
||||
}
|
||||
|
||||
ext := k.GetExtensions()
|
||||
if val, ok := ext["x-kubernetes-map-type"]; ok {
|
||||
switch val {
|
||||
case "atomic":
|
||||
a.Map.ElementRelationship = schema.Atomic
|
||||
case "granular":
|
||||
a.Map.ElementRelationship = schema.Separable
|
||||
default:
|
||||
c.reportError("unknown map type %v", val)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func toStringSlice(o interface{}) (out []string, ok bool) {
|
||||
@@ -384,37 +401,50 @@ func (c *convert) VisitMap(m *proto.Map) {
|
||||
a.Map = &schema.Map{}
|
||||
a.Map.ElementType = c.makeRef(m.SubType, c.preserveUnknownFields)
|
||||
|
||||
// TODO: Get element relationship when we start putting it into the
|
||||
// spec.
|
||||
ext := m.GetExtensions()
|
||||
if val, ok := ext["x-kubernetes-map-type"]; ok {
|
||||
switch val {
|
||||
case "atomic":
|
||||
a.Map.ElementRelationship = schema.Atomic
|
||||
case "granular":
|
||||
a.Map.ElementRelationship = schema.Separable
|
||||
default:
|
||||
c.reportError("unknown map type %v", val)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func ptr(s schema.Scalar) *schema.Scalar { return &s }
|
||||
|
||||
func (c *convert) VisitPrimitive(p *proto.Primitive) {
|
||||
a := c.top()
|
||||
switch p.Type {
|
||||
case proto.Integer:
|
||||
a.Scalar = ptr(schema.Numeric)
|
||||
case proto.Number:
|
||||
a.Scalar = ptr(schema.Numeric)
|
||||
case proto.String:
|
||||
switch p.Format {
|
||||
case "":
|
||||
a.Scalar = ptr(schema.String)
|
||||
case "byte":
|
||||
// byte really means []byte and is encoded as a string.
|
||||
a.Scalar = ptr(schema.String)
|
||||
case "int-or-string":
|
||||
a.Scalar = ptr(schema.Scalar("untyped"))
|
||||
case "date-time":
|
||||
a.Scalar = ptr(schema.Scalar("untyped"))
|
||||
if c.currentName == quantityResource {
|
||||
a.Scalar = ptr(schema.Scalar("untyped"))
|
||||
} else {
|
||||
switch p.Type {
|
||||
case proto.Integer:
|
||||
a.Scalar = ptr(schema.Numeric)
|
||||
case proto.Number:
|
||||
a.Scalar = ptr(schema.Numeric)
|
||||
case proto.String:
|
||||
switch p.Format {
|
||||
case "":
|
||||
a.Scalar = ptr(schema.String)
|
||||
case "byte":
|
||||
// byte really means []byte and is encoded as a string.
|
||||
a.Scalar = ptr(schema.String)
|
||||
case "int-or-string":
|
||||
a.Scalar = ptr(schema.Scalar("untyped"))
|
||||
case "date-time":
|
||||
a.Scalar = ptr(schema.Scalar("untyped"))
|
||||
default:
|
||||
a.Scalar = ptr(schema.Scalar("untyped"))
|
||||
}
|
||||
case proto.Boolean:
|
||||
a.Scalar = ptr(schema.Boolean)
|
||||
default:
|
||||
a.Scalar = ptr(schema.Scalar("untyped"))
|
||||
}
|
||||
case proto.Boolean:
|
||||
a.Scalar = ptr(schema.Boolean)
|
||||
default:
|
||||
a.Scalar = ptr(schema.Scalar("untyped"))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
64
vendor/k8s.io/kube-openapi/pkg/util/proto/document.go
generated
vendored
64
vendor/k8s.io/kube-openapi/pkg/util/proto/document.go
generated
vendored
@@ -21,7 +21,7 @@ import (
|
||||
"sort"
|
||||
"strings"
|
||||
|
||||
"github.com/googleapis/gnostic/OpenAPIv2"
|
||||
openapi_v2 "github.com/googleapis/gnostic/openapiv2"
|
||||
"gopkg.in/yaml.v2"
|
||||
)
|
||||
|
||||
@@ -109,19 +109,39 @@ func (d *Definitions) parseReference(s *openapi_v2.Schema, path *Path) (Schema,
|
||||
if _, ok := d.models[reference]; !ok {
|
||||
return nil, newSchemaError(path, "unknown model in reference: %q", reference)
|
||||
}
|
||||
base, err := d.parseBaseSchema(s, path)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &Ref{
|
||||
BaseSchema: d.parseBaseSchema(s, path),
|
||||
BaseSchema: base,
|
||||
reference: reference,
|
||||
definitions: d,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (d *Definitions) parseBaseSchema(s *openapi_v2.Schema, path *Path) BaseSchema {
|
||||
func parseDefault(def *openapi_v2.Any) (interface{}, error) {
|
||||
if def == nil {
|
||||
return nil, nil
|
||||
}
|
||||
var i interface{}
|
||||
if err := yaml.Unmarshal([]byte(def.Yaml), &i); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return i, nil
|
||||
}
|
||||
|
||||
func (d *Definitions) parseBaseSchema(s *openapi_v2.Schema, path *Path) (BaseSchema, error) {
|
||||
def, err := parseDefault(s.GetDefault())
|
||||
if err != nil {
|
||||
return BaseSchema{}, err
|
||||
}
|
||||
return BaseSchema{
|
||||
Description: s.GetDescription(),
|
||||
Default: def,
|
||||
Extensions: VendorExtensionToMap(s.GetVendorExtension()),
|
||||
Path: *path,
|
||||
}
|
||||
}, nil
|
||||
}
|
||||
|
||||
// We believe the schema is a map, verify and return a new schema
|
||||
@@ -132,8 +152,12 @@ func (d *Definitions) parseMap(s *openapi_v2.Schema, path *Path) (Schema, error)
|
||||
var sub Schema
|
||||
// TODO(incomplete): this misses the boolean case as AdditionalProperties is a bool+schema sum type.
|
||||
if s.GetAdditionalProperties().GetSchema() == nil {
|
||||
base, err := d.parseBaseSchema(s, path)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
sub = &Arbitrary{
|
||||
BaseSchema: d.parseBaseSchema(s, path),
|
||||
BaseSchema: base,
|
||||
}
|
||||
} else {
|
||||
var err error
|
||||
@@ -142,8 +166,12 @@ func (d *Definitions) parseMap(s *openapi_v2.Schema, path *Path) (Schema, error)
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
base, err := d.parseBaseSchema(s, path)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &Map{
|
||||
BaseSchema: d.parseBaseSchema(s, path),
|
||||
BaseSchema: base,
|
||||
SubType: sub,
|
||||
}, nil
|
||||
}
|
||||
@@ -165,8 +193,12 @@ func (d *Definitions) parsePrimitive(s *openapi_v2.Schema, path *Path) (Schema,
|
||||
default:
|
||||
return nil, newSchemaError(path, "Unknown primitive type: %q", t)
|
||||
}
|
||||
base, err := d.parseBaseSchema(s, path)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &Primitive{
|
||||
BaseSchema: d.parseBaseSchema(s, path),
|
||||
BaseSchema: base,
|
||||
Type: t,
|
||||
Format: s.GetFormat(),
|
||||
}, nil
|
||||
@@ -188,8 +220,12 @@ func (d *Definitions) parseArray(s *openapi_v2.Schema, path *Path) (Schema, erro
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
base, err := d.parseBaseSchema(s, path)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &Array{
|
||||
BaseSchema: d.parseBaseSchema(s, path),
|
||||
BaseSchema: base,
|
||||
SubType: sub,
|
||||
}, nil
|
||||
}
|
||||
@@ -216,8 +252,12 @@ func (d *Definitions) parseKind(s *openapi_v2.Schema, path *Path) (Schema, error
|
||||
fieldOrder = append(fieldOrder, name)
|
||||
}
|
||||
|
||||
base, err := d.parseBaseSchema(s, path)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &Kind{
|
||||
BaseSchema: d.parseBaseSchema(s, path),
|
||||
BaseSchema: base,
|
||||
RequiredFields: s.GetRequired(),
|
||||
Fields: fields,
|
||||
FieldOrder: fieldOrder,
|
||||
@@ -225,8 +265,12 @@ func (d *Definitions) parseKind(s *openapi_v2.Schema, path *Path) (Schema, error
|
||||
}
|
||||
|
||||
func (d *Definitions) parseArbitrary(s *openapi_v2.Schema, path *Path) (Schema, error) {
|
||||
base, err := d.parseBaseSchema(s, path)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &Arbitrary{
|
||||
BaseSchema: d.parseBaseSchema(s, path),
|
||||
BaseSchema: base,
|
||||
}, nil
|
||||
}
|
||||
|
||||
|
||||
7
vendor/k8s.io/kube-openapi/pkg/util/proto/openapi.go
generated
vendored
7
vendor/k8s.io/kube-openapi/pkg/util/proto/openapi.go
generated
vendored
@@ -77,6 +77,8 @@ type Schema interface {
|
||||
GetPath() *Path
|
||||
// Describes the field.
|
||||
GetDescription() string
|
||||
// Default for that schema.
|
||||
GetDefault() interface{}
|
||||
// Returns type extensions.
|
||||
GetExtensions() map[string]interface{}
|
||||
}
|
||||
@@ -129,6 +131,7 @@ func (p *Path) FieldPath(field string) Path {
|
||||
type BaseSchema struct {
|
||||
Description string
|
||||
Extensions map[string]interface{}
|
||||
Default interface{}
|
||||
|
||||
Path Path
|
||||
}
|
||||
@@ -141,6 +144,10 @@ func (b *BaseSchema) GetExtensions() map[string]interface{} {
|
||||
return b.Extensions
|
||||
}
|
||||
|
||||
func (b *BaseSchema) GetDefault() interface{} {
|
||||
return b.Default
|
||||
}
|
||||
|
||||
func (b *BaseSchema) GetPath() *Path {
|
||||
return &b.Path
|
||||
}
|
||||
|
||||
5
vendor/k8s.io/kube-openapi/pkg/util/util.go
generated
vendored
5
vendor/k8s.io/kube-openapi/pkg/util/util.go
generated
vendored
@@ -80,6 +80,9 @@ func ToRESTFriendlyName(name string) string {
|
||||
// Example for vendored Go type:
|
||||
// Original full path: k8s.io/kubernetes/vendor/k8s.io/api/core/v1.Pod
|
||||
// Canonical name: k8s.io/api/core/v1.Pod
|
||||
//
|
||||
// Original full path: vendor/k8s.io/api/core/v1.Pod
|
||||
// Canonical name: k8s.io/api/core/v1.Pod
|
||||
type OpenAPICanonicalTypeNamer interface {
|
||||
OpenAPICanonicalTypeName() string
|
||||
}
|
||||
@@ -100,6 +103,8 @@ func GetCanonicalTypeName(model interface{}) string {
|
||||
path := t.PkgPath()
|
||||
if strings.Contains(path, "/vendor/") {
|
||||
path = path[strings.Index(path, "/vendor/")+len("/vendor/"):]
|
||||
} else if strings.HasPrefix(path, "vendor/") {
|
||||
path = strings.TrimPrefix(path, "vendor/")
|
||||
}
|
||||
return path + "." + t.Name()
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user