kubernetes openapi 源码
kubernetes openapi 代码
文件路径:/staging/src/k8s.io/kubectl/pkg/apply/parse/openapi.go
/*
Copyright 2017 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 parse
import (
"fmt"
"strings"
"k8s.io/kube-openapi/pkg/util/proto"
)
// Contains functions for casting openapi interfaces to their underlying types
// getSchemaType returns the string type of the schema - e.g. array, primitive, map, kind, reference
func getSchemaType(schema proto.Schema) string {
if schema == nil {
return ""
}
visitor := &baseSchemaVisitor{}
schema.Accept(visitor)
return visitor.Kind
}
// getKind converts schema to an *proto.Kind object
func getKind(schema proto.Schema) (*proto.Kind, error) {
if schema == nil {
return nil, nil
}
visitor := &kindSchemaVisitor{}
schema.Accept(visitor)
return visitor.Result, visitor.Err
}
// getArray converts schema to an *proto.Array object
func getArray(schema proto.Schema) (*proto.Array, error) {
if schema == nil {
return nil, nil
}
visitor := &arraySchemaVisitor{}
schema.Accept(visitor)
return visitor.Result, visitor.Err
}
// getMap converts schema to an *proto.Map object
func getMap(schema proto.Schema) (*proto.Map, error) {
if schema == nil {
return nil, nil
}
visitor := &mapSchemaVisitor{}
schema.Accept(visitor)
return visitor.Result, visitor.Err
}
// getPrimitive converts schema to an *proto.Primitive object
func getPrimitive(schema proto.Schema) (*proto.Primitive, error) {
if schema == nil {
return nil, nil
}
visitor := &primitiveSchemaVisitor{}
schema.Accept(visitor)
return visitor.Result, visitor.Err
}
type baseSchemaVisitor struct {
Err error
Kind string
}
// VisitArray implements openapi
func (v *baseSchemaVisitor) VisitArray(array *proto.Array) {
v.Kind = "array"
v.Err = fmt.Errorf("Array type not expected")
}
// MergeMap implements openapi
func (v *baseSchemaVisitor) VisitMap(*proto.Map) {
v.Kind = "map"
v.Err = fmt.Errorf("Map type not expected")
}
// MergePrimitive implements openapi
func (v *baseSchemaVisitor) VisitPrimitive(*proto.Primitive) {
v.Kind = "primitive"
v.Err = fmt.Errorf("Primitive type not expected")
}
// VisitKind implements openapi
func (v *baseSchemaVisitor) VisitKind(*proto.Kind) {
v.Kind = "kind"
v.Err = fmt.Errorf("Kind type not expected")
}
// VisitReference implements openapi
func (v *baseSchemaVisitor) VisitReference(reference proto.Reference) {
v.Kind = "reference"
v.Err = fmt.Errorf("Reference type not expected")
}
type kindSchemaVisitor struct {
baseSchemaVisitor
Result *proto.Kind
}
// VisitKind implements openapi
func (v *kindSchemaVisitor) VisitKind(result *proto.Kind) {
v.Result = result
v.Kind = "kind"
}
// VisitReference implements openapi
func (v *kindSchemaVisitor) VisitReference(reference proto.Reference) {
reference.SubSchema().Accept(v)
if v.Err == nil {
v.Err = copyExtensions(reference.GetPath().String(), reference.GetExtensions(), v.Result.Extensions)
}
}
func copyExtensions(field string, from, to map[string]interface{}) error {
// Copy extensions from field to type for references
for key, val := range from {
if curr, found := to[key]; found {
// Don't allow the same extension to be defined both on the field and on the type
return fmt.Errorf("Cannot override value for extension %s on field %s from %v to %v",
key, field, curr, val)
}
to[key] = val
}
return nil
}
type mapSchemaVisitor struct {
baseSchemaVisitor
Result *proto.Map
}
// VisitMap implements openapi
func (v *mapSchemaVisitor) VisitMap(result *proto.Map) {
v.Result = result
v.Kind = "map"
}
// VisitReference implements openapi
func (v *mapSchemaVisitor) VisitReference(reference proto.Reference) {
reference.SubSchema().Accept(v)
if v.Err == nil {
v.Err = copyExtensions(reference.GetPath().String(), reference.GetExtensions(), v.Result.Extensions)
}
}
type arraySchemaVisitor struct {
baseSchemaVisitor
Result *proto.Array
}
// VisitArray implements openapi
func (v *arraySchemaVisitor) VisitArray(result *proto.Array) {
v.Result = result
v.Kind = "array"
v.Err = copySubElementPatchStrategy(result.Path.String(), result.GetExtensions(), result.SubType.GetExtensions())
}
// copySubElementPatchStrategy copies the strategies to subelements to the subtype
// e.g. PodTemplate.Volumes is a []Volume with "x-kubernetes-patch-strategy": "merge,retainKeys"
// the "retainKeys" strategy applies to merging Volumes, and must be copied to the sub element
func copySubElementPatchStrategy(field string, from, to map[string]interface{}) error {
// Check if the parent has a patch strategy extension
if ext, found := from["x-kubernetes-patch-strategy"]; found {
strategy, ok := ext.(string)
if !ok {
return fmt.Errorf("Expected string value for x-kubernetes-patch-strategy on %s, was %T",
field, ext)
}
// Check of the parent patch strategy has a sub patch strategy, and if so copy to the sub type
if strings.Contains(strategy, ",") {
strategies := strings.Split(strategy, ",")
if len(strategies) != 2 {
// Only 1 sub strategy is supported
return fmt.Errorf(
"Expected between 0 and 2 elements for x-kubernetes-patch-merge-strategy by got %v",
strategies)
}
to["x-kubernetes-patch-strategy"] = strategies[1]
}
}
return nil
}
// VisitReference implements openapi
func (v *arraySchemaVisitor) VisitReference(reference proto.Reference) {
reference.SubSchema().Accept(v)
if v.Err == nil {
v.Err = copyExtensions(reference.GetPath().String(), reference.GetExtensions(), v.Result.Extensions)
}
}
type primitiveSchemaVisitor struct {
baseSchemaVisitor
Result *proto.Primitive
}
// VisitPrimitive implements openapi
func (v *primitiveSchemaVisitor) VisitPrimitive(result *proto.Primitive) {
v.Result = result
v.Kind = "primitive"
}
// VisitReference implements openapi
func (v *primitiveSchemaVisitor) VisitReference(reference proto.Reference) {
reference.SubSchema().Accept(v)
if v.Err == nil {
v.Err = copyExtensions(reference.GetPath().String(), reference.GetExtensions(), v.Result.Extensions)
}
}
相关信息
相关文章
0
赞
热门推荐
-
2、 - 优质文章
-
3、 gate.io
-
8、 golang
-
9、 openharmony
-
10、 Vue中input框自动聚焦