mirror of
https://github.com/kubernetes-sigs/kustomize.git
synced 2026-06-11 17:12:51 +00:00
Use OpenAPI when merging (3way) resources
- When merging (3way) resources use the patch strategy from the openAPI if the definition exists for the field - Allow disabling of guessing patch strategy merge keys when no definition exists - Support defining strategy and key directly on configuration fields through line and header coments - Support attaching schema to parent fields of lists, and propagating -- e.g. that a field is a PodTemplate
This commit is contained in:
@@ -6,6 +6,8 @@ package walk
|
||||
import (
|
||||
"sort"
|
||||
|
||||
"sigs.k8s.io/kustomize/kyaml/fieldmeta"
|
||||
"sigs.k8s.io/kustomize/kyaml/openapi"
|
||||
"sigs.k8s.io/kustomize/kyaml/sets"
|
||||
"sigs.k8s.io/kustomize/kyaml/yaml"
|
||||
)
|
||||
@@ -18,15 +20,27 @@ import (
|
||||
// - set each source field value on l.Dest
|
||||
func (l Walker) walkMap() (*yaml.RNode, error) {
|
||||
// get the new map value
|
||||
dest, err := l.Sources.setDestNode(l.VisitMap(l.Sources))
|
||||
dest, err := l.Sources.setDestNode(l.VisitMap(l.Sources, l.Schema))
|
||||
if dest == nil || err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// recursively set the field values on the map
|
||||
for _, key := range l.fieldNames() {
|
||||
val, err := Walker{Visitor: l,
|
||||
Sources: l.fieldValue(key), Path: append(l.Path, key)}.Walk()
|
||||
var s *openapi.ResourceSchema
|
||||
if l.Schema != nil {
|
||||
s = l.Schema.Field(key)
|
||||
}
|
||||
fv, commentSch := l.fieldValue(key)
|
||||
if commentSch != nil {
|
||||
s = commentSch
|
||||
}
|
||||
val, err := Walker{
|
||||
InferAssociativeLists: l.InferAssociativeLists,
|
||||
Visitor: l,
|
||||
Schema: s,
|
||||
Sources: fv,
|
||||
Path: append(l.Path, key)}.Walk()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -42,11 +56,40 @@ func (l Walker) walkMap() (*yaml.RNode, error) {
|
||||
}
|
||||
|
||||
// valueIfPresent returns node.Value if node is non-nil, otherwise returns nil
|
||||
func (l Walker) valueIfPresent(node *yaml.MapNode) *yaml.RNode {
|
||||
func (l Walker) valueIfPresent(node *yaml.MapNode) (*yaml.RNode, *openapi.ResourceSchema) {
|
||||
if node == nil {
|
||||
return nil
|
||||
return nil, nil
|
||||
}
|
||||
return node.Value
|
||||
|
||||
// parse the schema for the field if present
|
||||
var s *openapi.ResourceSchema
|
||||
fm := fieldmeta.FieldMeta{}
|
||||
var err error
|
||||
// check the value for a schema
|
||||
if err = fm.Read(node.Value); err == nil {
|
||||
s = &openapi.ResourceSchema{Schema: &fm.Schema}
|
||||
if fm.Schema.Ref.String() != "" {
|
||||
r, err := openapi.Resolve(&fm.Schema.Ref)
|
||||
if err == nil && r != nil {
|
||||
s.Schema = r
|
||||
}
|
||||
}
|
||||
}
|
||||
// check the key for a schema -- this will be used
|
||||
// when the value is a Sequence (comments are attached)
|
||||
// to the key
|
||||
if fm.IsEmpty() {
|
||||
if err = fm.Read(node.Key); err == nil {
|
||||
s = &openapi.ResourceSchema{Schema: &fm.Schema}
|
||||
}
|
||||
if fm.Schema.Ref.String() != "" {
|
||||
r, err := openapi.Resolve(&fm.Schema.Ref)
|
||||
if err == nil && r != nil {
|
||||
s.Schema = r
|
||||
}
|
||||
}
|
||||
}
|
||||
return node.Value, s
|
||||
}
|
||||
|
||||
// fieldNames returns a sorted slice containing the names of all fields that appear in any of
|
||||
@@ -67,15 +110,20 @@ func (l Walker) fieldNames() []string {
|
||||
}
|
||||
|
||||
// fieldValue returns a slice containing each source's value for fieldName
|
||||
func (l Walker) fieldValue(fieldName string) []*yaml.RNode {
|
||||
func (l Walker) fieldValue(fieldName string) ([]*yaml.RNode, *openapi.ResourceSchema) {
|
||||
var fields []*yaml.RNode
|
||||
var sch *openapi.ResourceSchema
|
||||
for i := range l.Sources {
|
||||
if l.Sources[i] == nil {
|
||||
fields = append(fields, nil)
|
||||
continue
|
||||
}
|
||||
field := l.Sources[i].Field(fieldName)
|
||||
fields = append(fields, l.valueIfPresent(field))
|
||||
f, s := l.valueIfPresent(field)
|
||||
fields = append(fields, f)
|
||||
if sch == nil && !s.IsEmpty() {
|
||||
sch = s
|
||||
}
|
||||
}
|
||||
return fields
|
||||
return fields, sch
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user