mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-29 14:37:00 +00:00
kubectl apply parse libraries copy extensions to references and list elements
when getting field / type metadata from openapi, copy the openapi extensions from - references to the underlying type - lists to the subtype
This commit is contained in:
parent
1fef312102
commit
1b7118d965
@ -18,6 +18,7 @@ package parse
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"k8s.io/kube-openapi/pkg/util/proto"
|
||||
)
|
||||
@ -123,6 +124,22 @@ func (v *kindSchemaVisitor) VisitKind(result *proto.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 {
|
||||
@ -139,6 +156,9 @@ func (v *mapSchemaVisitor) VisitMap(result *proto.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 {
|
||||
@ -150,11 +170,41 @@ type arraySchemaVisitor struct {
|
||||
func (v *arraySchemaVisitor) VisitArray(result *proto.Array) {
|
||||
v.Result = result
|
||||
v.Kind = "array"
|
||||
v.Err = copySubElementPatchStrategy(result.Path.String(), result.GetExtensions(), result.SubType.GetExtensions())
|
||||
}
|
||||
|
||||
// copyPatchStrategy 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
|
||||
}
|
||||
|
||||
// MergePrimitive 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 {
|
||||
@ -171,4 +221,7 @@ func (v *primitiveSchemaVisitor) VisitPrimitive(result *proto.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)
|
||||
}
|
||||
}
|
||||
|
@ -101,13 +101,20 @@ func getFieldMeta(s proto.Schema, name string) (apply.FieldMetaImpl, error) {
|
||||
m := apply.FieldMetaImpl{}
|
||||
if s != nil {
|
||||
ext := s.GetExtensions()
|
||||
if s, found := ext["x-kubernetes-patch-strategy"]; found {
|
||||
strategy, ok := s.(string)
|
||||
if e, found := ext["x-kubernetes-patch-strategy"]; found {
|
||||
strategy, ok := e.(string)
|
||||
if !ok {
|
||||
return apply.FieldMetaImpl{}, fmt.Errorf("Expected string for x-kubernetes-patch-strategy by got %T", s)
|
||||
}
|
||||
// TODO: Support multi-strategy
|
||||
m.MergeType = strategy
|
||||
|
||||
// Take the first strategy if there are substrategies.
|
||||
// Sub strategies are copied to sub types in openapi.go
|
||||
strategies := strings.Split(strategy, ",")
|
||||
if len(strategies) > 2 {
|
||||
return apply.FieldMetaImpl{}, fmt.Errorf("Expected between 0 and 2 elements for x-kubernetes-patch-merge-strategy by got %v", strategies)
|
||||
}
|
||||
// For lists, choose the strategy for this type, not the subtype
|
||||
m.MergeType = strategies[0]
|
||||
}
|
||||
if k, found := ext["x-kubernetes-patch-merge-key"]; found {
|
||||
key, ok := k.(string)
|
||||
|
Loading…
Reference in New Issue
Block a user