Upgrade k8s package verison (#5358)
* upgrade k8s package version Signed-off-by: hongzhouzi <hongzhouzi@kubesphere.io> * Script upgrade and code formatting. Signed-off-by: hongzhouzi <hongzhouzi@kubesphere.io> Signed-off-by: hongzhouzi <hongzhouzi@kubesphere.io>
This commit is contained in:
65
vendor/sigs.k8s.io/structured-merge-diff/v4/merge/update.go
generated
vendored
65
vendor/sigs.k8s.io/structured-merge-diff/v4/merge/update.go
generated
vendored
@@ -250,35 +250,56 @@ func (s *Updater) addBackOwnedItems(merged, pruned *typed.TypedValue, managedFie
|
||||
}
|
||||
managedAtVersion[managerSet.APIVersion()] = managedAtVersion[managerSet.APIVersion()].Union(managerSet.Set())
|
||||
}
|
||||
// Add back owned items at pruned version first to avoid conversion failure
|
||||
// caused by pruned fields which are required for conversion.
|
||||
prunedVersion := fieldpath.APIVersion(*pruned.TypeRef().NamedType)
|
||||
if managed, ok := managedAtVersion[prunedVersion]; ok {
|
||||
merged, pruned, err = s.addBackOwnedItemsForVersion(merged, pruned, prunedVersion, managed)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
delete(managedAtVersion, prunedVersion)
|
||||
}
|
||||
for version, managed := range managedAtVersion {
|
||||
merged, err = s.Converter.Convert(merged, version)
|
||||
merged, pruned, err = s.addBackOwnedItemsForVersion(merged, pruned, version, managed)
|
||||
if err != nil {
|
||||
if s.Converter.IsMissingVersionError(err) {
|
||||
continue
|
||||
}
|
||||
return nil, fmt.Errorf("failed to convert merged object at version %v: %v", version, err)
|
||||
return nil, err
|
||||
}
|
||||
pruned, err = s.Converter.Convert(pruned, version)
|
||||
if err != nil {
|
||||
if s.Converter.IsMissingVersionError(err) {
|
||||
continue
|
||||
}
|
||||
return nil, fmt.Errorf("failed to convert pruned object at version %v: %v", version, err)
|
||||
}
|
||||
mergedSet, err := merged.ToFieldSet()
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to create field set from merged object at version %v: %v", version, err)
|
||||
}
|
||||
prunedSet, err := pruned.ToFieldSet()
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to create field set from pruned object at version %v: %v", version, err)
|
||||
}
|
||||
sc, tr := merged.Schema(), merged.TypeRef()
|
||||
pruned = merged.RemoveItems(mergedSet.EnsureNamedFieldsAreMembers(sc, tr).Difference(prunedSet.EnsureNamedFieldsAreMembers(sc, tr).Union(managed.EnsureNamedFieldsAreMembers(sc, tr))))
|
||||
}
|
||||
return pruned, nil
|
||||
}
|
||||
|
||||
// addBackOwnedItemsForVersion adds back any fields, list and map items that were removed by prune with specific managed field path at a version.
|
||||
// It is an extracted sub-function from addBackOwnedItems for code reuse.
|
||||
func (s *Updater) addBackOwnedItemsForVersion(merged, pruned *typed.TypedValue, version fieldpath.APIVersion, managed *fieldpath.Set) (*typed.TypedValue, *typed.TypedValue, error) {
|
||||
var err error
|
||||
merged, err = s.Converter.Convert(merged, version)
|
||||
if err != nil {
|
||||
if s.Converter.IsMissingVersionError(err) {
|
||||
return merged, pruned, nil
|
||||
}
|
||||
return nil, nil, fmt.Errorf("failed to convert merged object at version %v: %v", version, err)
|
||||
}
|
||||
pruned, err = s.Converter.Convert(pruned, version)
|
||||
if err != nil {
|
||||
if s.Converter.IsMissingVersionError(err) {
|
||||
return merged, pruned, nil
|
||||
}
|
||||
return nil, nil, fmt.Errorf("failed to convert pruned object at version %v: %v", version, err)
|
||||
}
|
||||
mergedSet, err := merged.ToFieldSet()
|
||||
if err != nil {
|
||||
return nil, nil, fmt.Errorf("failed to create field set from merged object at version %v: %v", version, err)
|
||||
}
|
||||
prunedSet, err := pruned.ToFieldSet()
|
||||
if err != nil {
|
||||
return nil, nil, fmt.Errorf("failed to create field set from pruned object at version %v: %v", version, err)
|
||||
}
|
||||
sc, tr := merged.Schema(), merged.TypeRef()
|
||||
pruned = merged.RemoveItems(mergedSet.EnsureNamedFieldsAreMembers(sc, tr).Difference(prunedSet.EnsureNamedFieldsAreMembers(sc, tr).Union(managed.EnsureNamedFieldsAreMembers(sc, tr))))
|
||||
return merged, pruned, nil
|
||||
}
|
||||
|
||||
// addBackDanglingItems makes sure that the fields list and map items removed by prune were
|
||||
// previously owned by the currently applying manager. This will add back fields list and map items
|
||||
// that are unowned or that are owned by Updaters and shouldn't be removed.
|
||||
|
||||
131
vendor/sigs.k8s.io/structured-merge-diff/v4/schema/elements.go
generated
vendored
131
vendor/sigs.k8s.io/structured-merge-diff/v4/schema/elements.go
generated
vendored
@@ -16,7 +16,9 @@ limitations under the License.
|
||||
|
||||
package schema
|
||||
|
||||
import "sync"
|
||||
import (
|
||||
"sync"
|
||||
)
|
||||
|
||||
// Schema is a list of named types.
|
||||
//
|
||||
@@ -27,6 +29,11 @@ type Schema struct {
|
||||
|
||||
once sync.Once
|
||||
m map[string]TypeDef
|
||||
|
||||
lock sync.Mutex
|
||||
// Cached results of resolving type references to atoms. Only stores
|
||||
// type references which require fields of Atom to be overriden.
|
||||
resolvedTypes map[TypeRef]Atom
|
||||
}
|
||||
|
||||
// A TypeSpecifier references a particular type in a schema.
|
||||
@@ -48,6 +55,12 @@ type TypeRef struct {
|
||||
// Either the name or one member of Atom should be set.
|
||||
NamedType *string `yaml:"namedType,omitempty"`
|
||||
Inlined Atom `yaml:",inline,omitempty"`
|
||||
|
||||
// If this reference refers to a map-type or list-type, this field overrides
|
||||
// the `ElementRelationship` of the referred type when resolved.
|
||||
// If this field is nil, then it has no effect.
|
||||
// See `Map` and `List` for more information about `ElementRelationship`
|
||||
ElementRelationship *ElementRelationship `yaml:"elementRelationship,omitempty"`
|
||||
}
|
||||
|
||||
// Atom represents the smallest possible pieces of the type system.
|
||||
@@ -88,11 +101,11 @@ const (
|
||||
|
||||
// Map is a key-value pair. Its default semantics are the same as an
|
||||
// associative list, but:
|
||||
// * It is serialized differently:
|
||||
// - It is serialized differently:
|
||||
// map: {"k": {"value": "v"}}
|
||||
// list: [{"key": "k", "value": "v"}]
|
||||
// * Keys must be string typed.
|
||||
// * Keys can't have multiple components.
|
||||
// - Keys must be string typed.
|
||||
// - Keys can't have multiple components.
|
||||
//
|
||||
// Optionally, maps may be atomic (for example, imagine representing an RGB
|
||||
// color value--it doesn't make sense to have different actors own the R and G
|
||||
@@ -146,6 +159,31 @@ func (m *Map) FindField(name string) (StructField, bool) {
|
||||
return sf, ok
|
||||
}
|
||||
|
||||
// CopyInto this instance of Map into the other
|
||||
// If other is nil this method does nothing.
|
||||
// If other is already initialized, overwrites it with this instance
|
||||
// Warning: Not thread safe
|
||||
func (m *Map) CopyInto(dst *Map) {
|
||||
if dst == nil {
|
||||
return
|
||||
}
|
||||
|
||||
// Map type is considered immutable so sharing references
|
||||
dst.Fields = m.Fields
|
||||
dst.ElementType = m.ElementType
|
||||
dst.Unions = m.Unions
|
||||
dst.ElementRelationship = m.ElementRelationship
|
||||
|
||||
if m.m != nil {
|
||||
// If cache is non-nil then the once token had been consumed.
|
||||
// Must reset token and use it again to ensure same semantics.
|
||||
dst.once = sync.Once{}
|
||||
dst.once.Do(func() {
|
||||
dst.m = m.m
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// UnionFields are mapping between the fields that are part of the union and
|
||||
// their discriminated value. The discriminated value has to be set, and
|
||||
// should not conflict with other discriminated value in the list.
|
||||
@@ -244,18 +282,93 @@ func (s *Schema) FindNamedType(name string) (TypeDef, bool) {
|
||||
return t, ok
|
||||
}
|
||||
|
||||
func (s *Schema) resolveNoOverrides(tr TypeRef) (Atom, bool) {
|
||||
result := Atom{}
|
||||
|
||||
if tr.NamedType != nil {
|
||||
t, ok := s.FindNamedType(*tr.NamedType)
|
||||
if !ok {
|
||||
return Atom{}, false
|
||||
}
|
||||
|
||||
result = t.Atom
|
||||
} else {
|
||||
result = tr.Inlined
|
||||
}
|
||||
|
||||
return result, true
|
||||
}
|
||||
|
||||
// Resolve is a convenience function which returns the atom referenced, whether
|
||||
// it is inline or named. Returns (Atom{}, false) if the type can't be resolved.
|
||||
//
|
||||
// This allows callers to not care about the difference between a (possibly
|
||||
// inlined) reference and a definition.
|
||||
func (s *Schema) Resolve(tr TypeRef) (Atom, bool) {
|
||||
if tr.NamedType != nil {
|
||||
t, ok := s.FindNamedType(*tr.NamedType)
|
||||
if !ok {
|
||||
// If this is a plain reference with no overrides, just return the type
|
||||
if tr.ElementRelationship == nil {
|
||||
return s.resolveNoOverrides(tr)
|
||||
}
|
||||
|
||||
s.lock.Lock()
|
||||
defer s.lock.Unlock()
|
||||
|
||||
if s.resolvedTypes == nil {
|
||||
s.resolvedTypes = make(map[TypeRef]Atom)
|
||||
}
|
||||
|
||||
var result Atom
|
||||
var exists bool
|
||||
|
||||
// Return cached result if available
|
||||
// If not, calculate result and cache it
|
||||
if result, exists = s.resolvedTypes[tr]; !exists {
|
||||
if result, exists = s.resolveNoOverrides(tr); exists {
|
||||
// Allow field-level electives to override the referred type's modifiers
|
||||
switch {
|
||||
case result.Map != nil:
|
||||
mapCopy := Map{}
|
||||
result.Map.CopyInto(&mapCopy)
|
||||
mapCopy.ElementRelationship = *tr.ElementRelationship
|
||||
result.Map = &mapCopy
|
||||
case result.List != nil:
|
||||
listCopy := *result.List
|
||||
listCopy.ElementRelationship = *tr.ElementRelationship
|
||||
result.List = &listCopy
|
||||
case result.Scalar != nil:
|
||||
return Atom{}, false
|
||||
default:
|
||||
return Atom{}, false
|
||||
}
|
||||
} else {
|
||||
return Atom{}, false
|
||||
}
|
||||
return t.Atom, true
|
||||
|
||||
// Save result. If it is nil, that is also recorded as not existing.
|
||||
s.resolvedTypes[tr] = result
|
||||
}
|
||||
|
||||
return result, true
|
||||
}
|
||||
|
||||
// Clones this instance of Schema into the other
|
||||
// If other is nil this method does nothing.
|
||||
// If other is already initialized, overwrites it with this instance
|
||||
// Warning: Not thread safe
|
||||
func (s *Schema) CopyInto(dst *Schema) {
|
||||
if dst == nil {
|
||||
return
|
||||
}
|
||||
|
||||
// Schema type is considered immutable so sharing references
|
||||
dst.Types = s.Types
|
||||
|
||||
if s.m != nil {
|
||||
// If cache is non-nil then the once token had been consumed.
|
||||
// Must reset token and use it again to ensure same semantics.
|
||||
dst.once = sync.Once{}
|
||||
dst.once.Do(func() {
|
||||
dst.m = s.m
|
||||
})
|
||||
}
|
||||
return tr.Inlined, true
|
||||
}
|
||||
|
||||
3
vendor/sigs.k8s.io/structured-merge-diff/v4/schema/equals.go
generated
vendored
3
vendor/sigs.k8s.io/structured-merge-diff/v4/schema/equals.go
generated
vendored
@@ -52,6 +52,9 @@ func (a *TypeRef) Equals(b *TypeRef) bool {
|
||||
}
|
||||
//return true
|
||||
}
|
||||
if a.ElementRelationship != b.ElementRelationship {
|
||||
return false
|
||||
}
|
||||
return a.Inlined.Equals(&b.Inlined)
|
||||
}
|
||||
|
||||
|
||||
3
vendor/sigs.k8s.io/structured-merge-diff/v4/schema/schemaschema.go
generated
vendored
3
vendor/sigs.k8s.io/structured-merge-diff/v4/schema/schemaschema.go
generated
vendored
@@ -66,6 +66,9 @@ var SchemaSchemaYAML = `types:
|
||||
- name: untyped
|
||||
type:
|
||||
namedType: untyped
|
||||
- name: elementRelationship
|
||||
type:
|
||||
scalar: string
|
||||
- name: scalar
|
||||
scalar: string
|
||||
- name: map
|
||||
|
||||
6
vendor/sigs.k8s.io/structured-merge-diff/v4/typed/helpers.go
generated
vendored
6
vendor/sigs.k8s.io/structured-merge-diff/v4/typed/helpers.go
generated
vendored
@@ -105,7 +105,11 @@ type atomHandler interface {
|
||||
func resolveSchema(s *schema.Schema, tr schema.TypeRef, v value.Value, ah atomHandler) ValidationErrors {
|
||||
a, ok := s.Resolve(tr)
|
||||
if !ok {
|
||||
return errorf("schema error: no type found matching: %v", *tr.NamedType)
|
||||
typeName := "inlined type"
|
||||
if tr.NamedType != nil {
|
||||
typeName = *tr.NamedType
|
||||
}
|
||||
return errorf("schema error: no type found matching: %v", typeName)
|
||||
}
|
||||
|
||||
a = deduceAtom(a, v)
|
||||
|
||||
191
vendor/sigs.k8s.io/structured-merge-diff/v4/typed/merge.go
generated
vendored
191
vendor/sigs.k8s.io/structured-merge-diff/v4/typed/merge.go
generated
vendored
@@ -17,8 +17,6 @@ limitations under the License.
|
||||
package typed
|
||||
|
||||
import (
|
||||
"math"
|
||||
|
||||
"sigs.k8s.io/structured-merge-diff/v4/fieldpath"
|
||||
"sigs.k8s.io/structured-merge-diff/v4/schema"
|
||||
"sigs.k8s.io/structured-merge-diff/v4/value"
|
||||
@@ -82,7 +80,12 @@ func (w *mergingWalker) merge(prefixFn func() string) (errs ValidationErrors) {
|
||||
|
||||
alhs := deduceAtom(a, w.lhs)
|
||||
arhs := deduceAtom(a, w.rhs)
|
||||
if alhs.Equals(&arhs) {
|
||||
|
||||
// deduceAtom does not fix the type for nil values
|
||||
// nil is a wildcard and will accept whatever form the other operand takes
|
||||
if w.rhs == nil {
|
||||
errs = append(errs, handleAtom(alhs, w.typeRef, w)...)
|
||||
} else if w.lhs == nil || alhs.Equals(&arhs) {
|
||||
errs = append(errs, handleAtom(arhs, w.typeRef, w)...)
|
||||
} else {
|
||||
w2 := *w
|
||||
@@ -170,78 +173,94 @@ func (w *mergingWalker) visitListItems(t *schema.List, lhs, rhs value.List) (err
|
||||
if lhs != nil {
|
||||
lLen = lhs.Length()
|
||||
}
|
||||
out := make([]interface{}, 0, int(math.Max(float64(rLen), float64(lLen))))
|
||||
outLen := lLen
|
||||
if outLen < rLen {
|
||||
outLen = rLen
|
||||
}
|
||||
out := make([]interface{}, 0, outLen)
|
||||
|
||||
// TODO: ordering is totally wrong.
|
||||
// TODO: might as well make the map order work the same way.
|
||||
rhsOrder, observedRHS, rhsErrs := w.indexListPathElements(t, rhs)
|
||||
errs = append(errs, rhsErrs...)
|
||||
lhsOrder, observedLHS, lhsErrs := w.indexListPathElements(t, lhs)
|
||||
errs = append(errs, lhsErrs...)
|
||||
|
||||
// This is a cheap hack to at least make the output order stable.
|
||||
rhsOrder := make([]fieldpath.PathElement, 0, rLen)
|
||||
|
||||
// First, collect all RHS children.
|
||||
observedRHS := fieldpath.MakePathElementValueMap(rLen)
|
||||
if rhs != nil {
|
||||
for i := 0; i < rhs.Length(); i++ {
|
||||
child := rhs.At(i)
|
||||
pe, err := listItemToPathElement(w.allocator, w.schema, t, i, child)
|
||||
if err != nil {
|
||||
errs = append(errs, errorf("rhs: element %v: %v", i, err.Error())...)
|
||||
// If we can't construct the path element, we can't
|
||||
// even report errors deeper in the schema, so bail on
|
||||
// this element.
|
||||
continue
|
||||
}
|
||||
if _, ok := observedRHS.Get(pe); ok {
|
||||
errs = append(errs, errorf("rhs: duplicate entries for key %v", pe.String())...)
|
||||
}
|
||||
observedRHS.Insert(pe, child)
|
||||
rhsOrder = append(rhsOrder, pe)
|
||||
sharedOrder := make([]*fieldpath.PathElement, 0, rLen)
|
||||
for i := range rhsOrder {
|
||||
pe := &rhsOrder[i]
|
||||
if _, ok := observedLHS.Get(*pe); ok {
|
||||
sharedOrder = append(sharedOrder, pe)
|
||||
}
|
||||
}
|
||||
|
||||
// Then merge with LHS children.
|
||||
observedLHS := fieldpath.MakePathElementSet(lLen)
|
||||
if lhs != nil {
|
||||
for i := 0; i < lhs.Length(); i++ {
|
||||
child := lhs.At(i)
|
||||
pe, err := listItemToPathElement(w.allocator, w.schema, t, i, child)
|
||||
if err != nil {
|
||||
errs = append(errs, errorf("lhs: element %v: %v", i, err.Error())...)
|
||||
// If we can't construct the path element, we can't
|
||||
// even report errors deeper in the schema, so bail on
|
||||
// this element.
|
||||
continue
|
||||
}
|
||||
if observedLHS.Has(pe) {
|
||||
errs = append(errs, errorf("lhs: duplicate entries for key %v", pe.String())...)
|
||||
continue
|
||||
}
|
||||
observedLHS.Insert(pe)
|
||||
w2 := w.prepareDescent(pe, t.ElementType)
|
||||
w2.lhs = value.Value(child)
|
||||
if rchild, ok := observedRHS.Get(pe); ok {
|
||||
w2.rhs = rchild
|
||||
}
|
||||
errs = append(errs, w2.merge(pe.String)...)
|
||||
if w2.out != nil {
|
||||
out = append(out, *w2.out)
|
||||
}
|
||||
w.finishDescent(w2)
|
||||
}
|
||||
var nextShared *fieldpath.PathElement
|
||||
if len(sharedOrder) > 0 {
|
||||
nextShared = sharedOrder[0]
|
||||
sharedOrder = sharedOrder[1:]
|
||||
}
|
||||
|
||||
for _, pe := range rhsOrder {
|
||||
if observedLHS.Has(pe) {
|
||||
continue
|
||||
lLen, rLen = len(lhsOrder), len(rhsOrder)
|
||||
for lI, rI := 0, 0; lI < lLen || rI < rLen; {
|
||||
if lI < lLen && rI < rLen {
|
||||
pe := lhsOrder[lI]
|
||||
if pe.Equals(rhsOrder[rI]) {
|
||||
// merge LHS & RHS items
|
||||
lChild, _ := observedLHS.Get(pe)
|
||||
rChild, _ := observedRHS.Get(pe)
|
||||
mergeOut, errs := w.mergeListItem(t, pe, lChild, rChild)
|
||||
errs = append(errs, errs...)
|
||||
if mergeOut != nil {
|
||||
out = append(out, *mergeOut)
|
||||
}
|
||||
lI++
|
||||
rI++
|
||||
|
||||
nextShared = nil
|
||||
if len(sharedOrder) > 0 {
|
||||
nextShared = sharedOrder[0]
|
||||
sharedOrder = sharedOrder[1:]
|
||||
}
|
||||
continue
|
||||
}
|
||||
if _, ok := observedRHS.Get(pe); ok && nextShared != nil && !nextShared.Equals(lhsOrder[lI]) {
|
||||
// shared item, but not the one we want in this round
|
||||
lI++
|
||||
continue
|
||||
}
|
||||
}
|
||||
value, _ := observedRHS.Get(pe)
|
||||
w2 := w.prepareDescent(pe, t.ElementType)
|
||||
w2.rhs = value
|
||||
errs = append(errs, w2.merge(pe.String)...)
|
||||
if w2.out != nil {
|
||||
out = append(out, *w2.out)
|
||||
if lI < lLen {
|
||||
pe := lhsOrder[lI]
|
||||
if _, ok := observedRHS.Get(pe); !ok {
|
||||
// take LHS item
|
||||
lChild, _ := observedLHS.Get(pe)
|
||||
mergeOut, errs := w.mergeListItem(t, pe, lChild, nil)
|
||||
errs = append(errs, errs...)
|
||||
if mergeOut != nil {
|
||||
out = append(out, *mergeOut)
|
||||
}
|
||||
lI++
|
||||
continue
|
||||
}
|
||||
}
|
||||
if rI < rLen {
|
||||
// Take the RHS item, merge with matching LHS item if possible
|
||||
pe := rhsOrder[rI]
|
||||
lChild, _ := observedLHS.Get(pe) // may be nil
|
||||
rChild, _ := observedRHS.Get(pe)
|
||||
mergeOut, errs := w.mergeListItem(t, pe, lChild, rChild)
|
||||
errs = append(errs, errs...)
|
||||
if mergeOut != nil {
|
||||
out = append(out, *mergeOut)
|
||||
}
|
||||
rI++
|
||||
// Advance nextShared, if we are merging nextShared.
|
||||
if nextShared != nil && nextShared.Equals(pe) {
|
||||
nextShared = nil
|
||||
if len(sharedOrder) > 0 {
|
||||
nextShared = sharedOrder[0]
|
||||
sharedOrder = sharedOrder[1:]
|
||||
}
|
||||
}
|
||||
}
|
||||
w.finishDescent(w2)
|
||||
}
|
||||
|
||||
if len(out) > 0 {
|
||||
@@ -252,6 +271,46 @@ func (w *mergingWalker) visitListItems(t *schema.List, lhs, rhs value.List) (err
|
||||
return errs
|
||||
}
|
||||
|
||||
func (w *mergingWalker) indexListPathElements(t *schema.List, list value.List) ([]fieldpath.PathElement, fieldpath.PathElementValueMap, ValidationErrors) {
|
||||
var errs ValidationErrors
|
||||
length := 0
|
||||
if list != nil {
|
||||
length = list.Length()
|
||||
}
|
||||
observed := fieldpath.MakePathElementValueMap(length)
|
||||
pes := make([]fieldpath.PathElement, 0, length)
|
||||
for i := 0; i < length; i++ {
|
||||
child := list.At(i)
|
||||
pe, err := listItemToPathElement(w.allocator, w.schema, t, i, child)
|
||||
if err != nil {
|
||||
errs = append(errs, errorf("element %v: %v", i, err.Error())...)
|
||||
// If we can't construct the path element, we can't
|
||||
// even report errors deeper in the schema, so bail on
|
||||
// this element.
|
||||
continue
|
||||
}
|
||||
if _, found := observed.Get(pe); found {
|
||||
errs = append(errs, errorf("duplicate entries for key %v", pe.String())...)
|
||||
continue
|
||||
}
|
||||
observed.Insert(pe, child)
|
||||
pes = append(pes, pe)
|
||||
}
|
||||
return pes, observed, errs
|
||||
}
|
||||
|
||||
func (w *mergingWalker) mergeListItem(t *schema.List, pe fieldpath.PathElement, lChild, rChild value.Value) (out *interface{}, errs ValidationErrors) {
|
||||
w2 := w.prepareDescent(pe, t.ElementType)
|
||||
w2.lhs = lChild
|
||||
w2.rhs = rChild
|
||||
errs = append(errs, w2.merge(pe.String)...)
|
||||
if w2.out != nil {
|
||||
out = w2.out
|
||||
}
|
||||
w.finishDescent(w2)
|
||||
return
|
||||
}
|
||||
|
||||
func (w *mergingWalker) derefList(prefix string, v value.Value) (value.List, ValidationErrors) {
|
||||
if v == nil {
|
||||
return nil, nil
|
||||
|
||||
73
vendor/sigs.k8s.io/structured-merge-diff/v4/typed/reconcile_schema.go
generated
vendored
73
vendor/sigs.k8s.io/structured-merge-diff/v4/typed/reconcile_schema.go
generated
vendored
@@ -110,7 +110,7 @@ func (v *reconcileWithSchemaWalker) finishDescent(v2 *reconcileWithSchemaWalker)
|
||||
}
|
||||
|
||||
// ReconcileFieldSetWithSchema reconciles the a field set with any changes to the
|
||||
//// object's schema since the field set was written. Returns the reconciled field set, or nil of
|
||||
// object's schema since the field set was written. Returns the reconciled field set, or nil of
|
||||
// no changes were made to the field set.
|
||||
//
|
||||
// Supports:
|
||||
@@ -124,13 +124,6 @@ func ReconcileFieldSetWithSchema(fieldset *fieldpath.Set, tv *TypedValue) (*fiel
|
||||
v.schema = tv.schema
|
||||
v.typeRef = tv.typeRef
|
||||
|
||||
// We don't reconcile deduced types, which are primarily for use by unstructured CRDs. Deduced
|
||||
// types do not support atomic or granular tags. Nor does the dynamic schema deduction
|
||||
// interact well with the reconcile logic.
|
||||
if v.schema == DeducedParseableType.Schema {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
defer v.finished()
|
||||
errs := v.reconcile()
|
||||
|
||||
@@ -187,19 +180,17 @@ func (v *reconcileWithSchemaWalker) visitListItems(t *schema.List, element *fiel
|
||||
}
|
||||
|
||||
func (v *reconcileWithSchemaWalker) doList(t *schema.List) (errs ValidationErrors) {
|
||||
// reconcile lists changed from granular to atomic
|
||||
// reconcile lists changed from granular to atomic.
|
||||
// Note that migrations from atomic to granular are not recommended and will
|
||||
// be treated as if they were always granular.
|
||||
//
|
||||
// In this case, the manager that owned the previously atomic field (and all subfields),
|
||||
// will now own just the top-level field and none of the subfields.
|
||||
if !v.isAtomic && t.ElementRelationship == schema.Atomic {
|
||||
v.toRemove = fieldpath.NewSet(v.path) // remove all root and all children fields
|
||||
v.toAdd = fieldpath.NewSet(v.path) // add the root of the atomic
|
||||
return errs
|
||||
}
|
||||
// reconcile lists changed from atomic to granular
|
||||
if v.isAtomic && t.ElementRelationship == schema.Associative {
|
||||
v.toAdd, errs = buildGranularFieldSet(v.path, v.value)
|
||||
if errs != nil {
|
||||
return errs
|
||||
}
|
||||
}
|
||||
if v.fieldSet != nil {
|
||||
errs = v.visitListItems(t, v.fieldSet)
|
||||
}
|
||||
@@ -231,7 +222,18 @@ func (v *reconcileWithSchemaWalker) visitMapItems(t *schema.Map, element *fieldp
|
||||
}
|
||||
|
||||
func (v *reconcileWithSchemaWalker) doMap(t *schema.Map) (errs ValidationErrors) {
|
||||
// reconcile maps and structs changed from granular to atomic
|
||||
// We don't currently reconcile deduced types (unstructured CRDs) or maps that contain only unknown
|
||||
// fields since deduced types do not yet support atomic or granular tags.
|
||||
if isUntypedDeducedMap(t) {
|
||||
return errs
|
||||
}
|
||||
|
||||
// reconcile maps and structs changed from granular to atomic.
|
||||
// Note that migrations from atomic to granular are not recommended and will
|
||||
// be treated as if they were always granular.
|
||||
//
|
||||
// In this case the manager that owned the previously atomic field (and all subfields),
|
||||
// will now own just the top-level field and none of the subfields.
|
||||
if !v.isAtomic && t.ElementRelationship == schema.Atomic {
|
||||
if v.fieldSet != nil && v.fieldSet.Size() > 0 {
|
||||
v.toRemove = fieldpath.NewSet(v.path) // remove all root and all children fields
|
||||
@@ -239,34 +241,12 @@ func (v *reconcileWithSchemaWalker) doMap(t *schema.Map) (errs ValidationErrors)
|
||||
}
|
||||
return errs
|
||||
}
|
||||
// reconcile maps changed from atomic to granular
|
||||
if v.isAtomic && (t.ElementRelationship == schema.Separable || t.ElementRelationship == "") {
|
||||
v.toAdd, errs = buildGranularFieldSet(v.path, v.value)
|
||||
if errs != nil {
|
||||
return errs
|
||||
}
|
||||
}
|
||||
if v.fieldSet != nil {
|
||||
errs = v.visitMapItems(t, v.fieldSet)
|
||||
}
|
||||
return errs
|
||||
}
|
||||
|
||||
func buildGranularFieldSet(path fieldpath.Path, value *TypedValue) (*fieldpath.Set, ValidationErrors) {
|
||||
|
||||
valueFieldSet, err := value.ToFieldSet()
|
||||
if err != nil {
|
||||
return nil, errorf("toFieldSet: %v", err)
|
||||
}
|
||||
if valueFieldSetAtPath, ok := fieldSetAtPath(valueFieldSet, path); ok {
|
||||
result := fieldpath.NewSet(path)
|
||||
resultAtPath := descendToPath(result, path)
|
||||
*resultAtPath = *valueFieldSetAtPath
|
||||
return result, nil
|
||||
}
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func fieldSetAtPath(node *fieldpath.Set, path fieldpath.Path) (*fieldpath.Set, bool) {
|
||||
ok := true
|
||||
for _, pe := range path {
|
||||
@@ -293,3 +273,18 @@ func typeRefAtPath(t *schema.Map, pe fieldpath.PathElement) (schema.TypeRef, boo
|
||||
}
|
||||
return tr, tr != schema.TypeRef{}
|
||||
}
|
||||
|
||||
// isUntypedDeducedMap returns true if m has no fields defined, but allows untyped elements.
|
||||
// This is equivalent to a openAPI object that has x-kubernetes-preserve-unknown-fields=true
|
||||
// but does not have any properties defined on the object.
|
||||
func isUntypedDeducedMap(m *schema.Map) bool {
|
||||
return isUntypedDeducedRef(m.ElementType) && m.Fields == nil
|
||||
}
|
||||
|
||||
func isUntypedDeducedRef(t schema.TypeRef) bool {
|
||||
if t.NamedType != nil {
|
||||
return *t.NamedType == "__untyped_deduced_"
|
||||
}
|
||||
atom := t.Inlined
|
||||
return atom.Scalar != nil && *atom.Scalar == "untyped"
|
||||
}
|
||||
|
||||
37
vendor/sigs.k8s.io/structured-merge-diff/v4/typed/remove.go
generated
vendored
37
vendor/sigs.k8s.io/structured-merge-diff/v4/typed/remove.go
generated
vendored
@@ -51,10 +51,22 @@ func (w *removingWalker) doScalar(t *schema.Scalar) ValidationErrors {
|
||||
}
|
||||
|
||||
func (w *removingWalker) doList(t *schema.List) (errs ValidationErrors) {
|
||||
if !w.value.IsList() {
|
||||
return nil
|
||||
}
|
||||
l := w.value.AsListUsing(w.allocator)
|
||||
defer w.allocator.Free(l)
|
||||
// If list is null, empty, or atomic just return
|
||||
if l == nil || l.Length() == 0 || t.ElementRelationship == schema.Atomic {
|
||||
// If list is null or empty just return
|
||||
if l == nil || l.Length() == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
// atomic lists should return everything in the case of extract
|
||||
// and nothing in the case of remove (!w.shouldExtract)
|
||||
if t.ElementRelationship == schema.Atomic {
|
||||
if w.shouldExtract {
|
||||
w.out = w.value.Unstructured()
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -70,7 +82,7 @@ func (w *removingWalker) doList(t *schema.List) (errs ValidationErrors) {
|
||||
// but ignore them when we are removing (i.e. !w.shouldExtract)
|
||||
if w.toRemove.Has(path) {
|
||||
if w.shouldExtract {
|
||||
newItems = append(newItems, item.Unstructured())
|
||||
newItems = append(newItems, removeItemsWithSchema(item, w.toRemove, w.schema, t.ElementType, w.shouldExtract).Unstructured())
|
||||
} else {
|
||||
continue
|
||||
}
|
||||
@@ -92,12 +104,24 @@ func (w *removingWalker) doList(t *schema.List) (errs ValidationErrors) {
|
||||
}
|
||||
|
||||
func (w *removingWalker) doMap(t *schema.Map) ValidationErrors {
|
||||
if !w.value.IsMap() {
|
||||
return nil
|
||||
}
|
||||
m := w.value.AsMapUsing(w.allocator)
|
||||
if m != nil {
|
||||
defer w.allocator.Free(m)
|
||||
}
|
||||
// If map is null, empty, or atomic just return
|
||||
if m == nil || m.Empty() || t.ElementRelationship == schema.Atomic {
|
||||
// If map is null or empty just return
|
||||
if m == nil || m.Empty() {
|
||||
return nil
|
||||
}
|
||||
|
||||
// atomic maps should return everything in the case of extract
|
||||
// and nothing in the case of remove (!w.shouldExtract)
|
||||
if t.ElementRelationship == schema.Atomic {
|
||||
if w.shouldExtract {
|
||||
w.out = w.value.Unstructured()
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -118,7 +142,8 @@ func (w *removingWalker) doMap(t *schema.Map) ValidationErrors {
|
||||
// but ignore them when we are removing (i.e. !w.shouldExtract)
|
||||
if w.toRemove.Has(path) {
|
||||
if w.shouldExtract {
|
||||
newMap[k] = val.Unstructured()
|
||||
newMap[k] = removeItemsWithSchema(val, w.toRemove, w.schema, fieldType, w.shouldExtract).Unstructured()
|
||||
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
13
vendor/sigs.k8s.io/structured-merge-diff/v4/typed/typed.go
generated
vendored
13
vendor/sigs.k8s.io/structured-merge-diff/v4/typed/typed.go
generated
vendored
@@ -99,12 +99,13 @@ func (tv TypedValue) ToFieldSet() (*fieldpath.Set, error) {
|
||||
|
||||
// Merge returns the result of merging tv and pso ("partially specified
|
||||
// object") together. Of note:
|
||||
// * No fields can be removed by this operation.
|
||||
// * If both tv and pso specify a given leaf field, the result will keep pso's
|
||||
// value.
|
||||
// * Container typed elements will have their items ordered:
|
||||
// * like tv, if pso doesn't change anything in the container
|
||||
// * like pso, if pso does change something in the container.
|
||||
// - No fields can be removed by this operation.
|
||||
// - If both tv and pso specify a given leaf field, the result will keep pso's
|
||||
// value.
|
||||
// - Container typed elements will have their items ordered:
|
||||
// 1. like tv, if pso doesn't change anything in the container
|
||||
// 2. like pso, if pso does change something in the container.
|
||||
//
|
||||
// tv and pso must both be of the same type (their Schema and TypeRef must
|
||||
// match), or an error will be returned. Validation errors will be returned if
|
||||
// the objects don't conform to the schema.
|
||||
|
||||
Reference in New Issue
Block a user