mirror of
https://github.com/kubernetes-sigs/kustomize.git
synced 2026-05-17 18:25:26 +00:00
Merge pull request #3987 from mortent/AddResourceHandlerForMerge3
Allow users to customize handling of deleted resources for merge3
This commit is contained in:
@@ -30,6 +30,36 @@ type ResourceMatcher interface {
|
||||
IsSameResource(node1, node2 *yaml.RNode) bool
|
||||
}
|
||||
|
||||
// ResourceMergeStrategy is the return type from the Handle function in the
|
||||
// ResourceHandler interface. It determines which version of a resource should
|
||||
// be included in the output (if any).
|
||||
type ResourceMergeStrategy int
|
||||
|
||||
const (
|
||||
// Merge means the output to dest should be the 3-way merge of original,
|
||||
// updated and dest.
|
||||
Merge ResourceMergeStrategy = iota
|
||||
// KeepDest means the version of the resource in dest should be the output.
|
||||
KeepDest
|
||||
// KeepUpdated means the version of the resource in updated should be the
|
||||
// output.
|
||||
KeepUpdated
|
||||
// KeepOriginal means the version of the resource in original should be the
|
||||
// output.
|
||||
KeepOriginal
|
||||
// Skip means the resource should not be included in the output.
|
||||
Skip
|
||||
)
|
||||
|
||||
// ResourceHandler interface is used to determine what should be done for a
|
||||
// resource once the versions in original, updated and dest has been
|
||||
// identified based on the ResourceMatcher. This allows users to customize
|
||||
// what should be the result in dest if a resource has been deleted from
|
||||
// upstream.
|
||||
type ResourceHandler interface {
|
||||
Handle(original, updated, dest *yaml.RNode) ResourceMergeStrategy
|
||||
}
|
||||
|
||||
// Merge3 performs a 3-way merge on the original, updated, and destination packages.
|
||||
type Merge3 struct {
|
||||
OriginalPath string
|
||||
@@ -37,6 +67,7 @@ type Merge3 struct {
|
||||
DestPath string
|
||||
MatchFilesGlob []string
|
||||
Matcher ResourceMatcher
|
||||
Handler ResourceHandler
|
||||
}
|
||||
|
||||
func (m Merge3) Merge() error {
|
||||
@@ -78,6 +109,11 @@ func (m Merge3) Filter(nodes []*yaml.RNode) ([]*yaml.RNode, error) {
|
||||
if matcher == nil {
|
||||
matcher = &DefaultGVKNNMatcher{MergeOnPath: true}
|
||||
}
|
||||
handler := m.Handler
|
||||
if handler == nil {
|
||||
handler = &DefaultResourceHandler{}
|
||||
}
|
||||
|
||||
tl := tuples{matcher: matcher}
|
||||
for i := range nodes {
|
||||
if err := tl.add(nodes[i]); err != nil {
|
||||
@@ -89,21 +125,9 @@ func (m Merge3) Filter(nodes []*yaml.RNode) ([]*yaml.RNode, error) {
|
||||
var output []*yaml.RNode
|
||||
for i := range tl.list {
|
||||
t := tl.list[i]
|
||||
switch {
|
||||
case t.original == nil && t.updated == nil && t.dest != nil:
|
||||
// added locally -- keep dest
|
||||
output = append(output, t.dest)
|
||||
case t.updated != nil && t.dest == nil:
|
||||
// added in the update -- add update
|
||||
output = append(output, t.updated)
|
||||
case t.original != nil && t.updated == nil:
|
||||
// deleted in the update
|
||||
// don't include the resource in the output
|
||||
case t.original != nil && t.dest == nil:
|
||||
// deleted locally
|
||||
// don't include the resource in the output
|
||||
default:
|
||||
// dest and updated are non-nil -- merge them
|
||||
strategy := handler.Handle(t.original, t.updated, t.dest)
|
||||
switch strategy {
|
||||
case Merge:
|
||||
node, err := t.merge()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -111,6 +135,14 @@ func (m Merge3) Filter(nodes []*yaml.RNode) ([]*yaml.RNode, error) {
|
||||
if node != nil {
|
||||
output = append(output, node)
|
||||
}
|
||||
case KeepDest:
|
||||
output = append(output, t.dest)
|
||||
case KeepUpdated:
|
||||
output = append(output, t.updated)
|
||||
case KeepOriginal:
|
||||
output = append(output, t.original)
|
||||
case Skip:
|
||||
// do nothing
|
||||
}
|
||||
}
|
||||
return output, nil
|
||||
@@ -245,3 +277,32 @@ func (t *tuple) merge() (*yaml.RNode, error) {
|
||||
func duplicateError(source, filePath string) error {
|
||||
return fmt.Errorf(`found duplicate %q resources in file %q, please refer to "update" documentation for the fix`, source, filePath)
|
||||
}
|
||||
|
||||
// DefaultResourceHandler is the default implementation of the ResourceHandler
|
||||
// interface. It uses the following rules:
|
||||
// * Keep dest if resource only exists in dest.
|
||||
// * Keep updated if resource added in updated.
|
||||
// * Delete dest if updated has been deleted.
|
||||
// * Don't add the resource back if removed from dest.
|
||||
// * Otherwise merge.
|
||||
type DefaultResourceHandler struct{}
|
||||
|
||||
func (*DefaultResourceHandler) Handle(original, updated, dest *yaml.RNode) ResourceMergeStrategy {
|
||||
switch {
|
||||
case original == nil && updated == nil && dest != nil:
|
||||
// added locally -- keep dest
|
||||
return KeepDest
|
||||
case updated != nil && dest == nil:
|
||||
// added in the update -- add update
|
||||
return KeepUpdated
|
||||
case original != nil && updated == nil:
|
||||
// deleted in the update
|
||||
return Skip
|
||||
case original != nil && dest == nil:
|
||||
// deleted locally
|
||||
return Skip
|
||||
default:
|
||||
// dest and updated are non-nil -- merge them
|
||||
return Merge
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user