Start supporting strategic merge patch in kyaml merge2.

This commit is contained in:
jregan
2020-06-28 11:39:14 -07:00
parent 2153863355
commit ef04983392
7 changed files with 375 additions and 2 deletions

View File

@@ -0,0 +1,71 @@
// Copyright 2019 The Kubernetes Authors.
// SPDX-License-Identifier: Apache-2.0
package merge2
import (
"fmt"
"sigs.k8s.io/kustomize/kyaml/yaml"
)
// A strategic merge patch directive.
// See https://github.com/kubernetes/community/blob/master/contributors/devel/sig-api-machinery/strategic-merge-patch.md
//
//go:generate stringer -type=smpDirective -linecomment
type smpDirective int
const (
smpUnknown smpDirective = iota // unknown
smpReplace // replace
smpDelete // delete
smpMerge // merge
)
const strategicMergePatchDirectiveKey = "$patch"
// Examine patch for a strategic merge patch directive.
// If found, return it, and remove the directive from the patch.
func determineSmpDirective(patch *yaml.RNode) (smpDirective, error) {
if patch == nil {
return smpMerge, nil
}
switch patch.YNode().Kind {
case yaml.SequenceNode:
return determineSequenceNodePatchStrategy(patch)
case yaml.MappingNode:
return determineMappingNodePatchStrategy(patch)
default:
return smpUnknown, fmt.Errorf(
"no implemented strategic merge patch strategy for '%s' ('%s')",
patch.YNode().ShortTag(), patch.MustString())
}
}
// TODO: what should this do?
func determineSequenceNodePatchStrategy(_ *yaml.RNode) (smpDirective, error) {
return smpMerge, nil
}
func determineMappingNodePatchStrategy(patch *yaml.RNode) (smpDirective, error) {
node, err := patch.Pipe(yaml.Get(strategicMergePatchDirectiveKey))
if err != nil || node == nil || node.YNode() == nil {
return smpMerge, nil
}
v := node.YNode().Value
if v == smpDelete.String() {
return smpDelete, elidePatchDirective(patch)
}
if v == smpReplace.String() {
return smpReplace, elidePatchDirective(patch)
}
if v == smpMerge.String() {
return smpMerge, elidePatchDirective(patch)
}
return smpUnknown, fmt.Errorf(
"unknown patch strategy '%s'", v)
}
func elidePatchDirective(patch *yaml.RNode) error {
return patch.PipeE(yaml.Clear(strategicMergePatchDirectiveKey))
}