mirror of
https://github.com/kubernetes-sigs/kustomize.git
synced 2026-07-17 17:52:12 +00:00
Handle ordering patches with SMP delete directives
This change enables the SMP patch merging process to support delete directives in patches regardless of input order.
This commit is contained in:
@@ -6,12 +6,13 @@ package patch
|
|||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||||
"k8s.io/client-go/kubernetes/scheme"
|
"k8s.io/client-go/kubernetes/scheme"
|
||||||
"sigs.k8s.io/kustomize/v3/pkg/gvk"
|
"sigs.k8s.io/kustomize/v3/pkg/gvk"
|
||||||
"sigs.k8s.io/kustomize/v3/pkg/resmap"
|
"sigs.k8s.io/kustomize/v3/pkg/resmap"
|
||||||
|
|
||||||
"github.com/evanphx/json-patch"
|
jsonpatch "github.com/evanphx/json-patch"
|
||||||
"k8s.io/apimachinery/pkg/runtime"
|
"k8s.io/apimachinery/pkg/runtime"
|
||||||
"k8s.io/apimachinery/pkg/util/mergepatch"
|
"k8s.io/apimachinery/pkg/util/mergepatch"
|
||||||
"k8s.io/apimachinery/pkg/util/strategicpatch"
|
"k8s.io/apimachinery/pkg/util/strategicpatch"
|
||||||
@@ -123,12 +124,18 @@ func (smp *strategicMergePatch) findConflict(
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (smp *strategicMergePatch) mergePatches(patch1, patch2 *resource.Resource) (*resource.Resource, error) {
|
func (smp *strategicMergePatch) mergePatches(patch1, patch2 *resource.Resource) (*resource.Resource, error) {
|
||||||
|
if hasDeleteDirectiveMarker(patch2.Map()) {
|
||||||
|
if hasDeleteDirectiveMarker(patch1.Map()) {
|
||||||
|
return nil, fmt.Errorf("cannot merge patches both containing '$patch: delete' directives")
|
||||||
|
}
|
||||||
|
patch1, patch2 = patch2, patch1
|
||||||
|
}
|
||||||
mergeJSONMap, err := strategicpatch.MergeStrategicMergeMapPatchUsingLookupPatchMeta(
|
mergeJSONMap, err := strategicpatch.MergeStrategicMergeMapPatchUsingLookupPatchMeta(
|
||||||
smp.lookupPatchMeta, patch1.Map(), patch2.Map())
|
smp.lookupPatchMeta, patch1.Map(), patch2.Map())
|
||||||
return smp.rf.FromMap(mergeJSONMap), err
|
return smp.rf.FromMap(mergeJSONMap), err
|
||||||
}
|
}
|
||||||
|
|
||||||
// mergePatches merge and index patches by OrgId.
|
// MergePatches merge and index patches by OrgId.
|
||||||
// It errors out if there is conflict between patches.
|
// It errors out if there is conflict between patches.
|
||||||
func MergePatches(patches []*resource.Resource,
|
func MergePatches(patches []*resource.Resource,
|
||||||
rf *resource.Factory) (resmap.ResMap, error) {
|
rf *resource.Factory) (resmap.ResMap, error) {
|
||||||
@@ -188,3 +195,28 @@ func toSchemaGvk(x gvk.Gvk) schema.GroupVersionKind {
|
|||||||
Kind: x.Kind,
|
Kind: x.Kind,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func hasDeleteDirectiveMarker(patch map[string]interface{}) bool {
|
||||||
|
if v, ok := patch["$patch"]; ok && v == "delete" {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
for _, v := range patch {
|
||||||
|
switch typedV := v.(type) {
|
||||||
|
case map[string]interface{}:
|
||||||
|
if hasDeleteDirectiveMarker(typedV) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
case []interface{}:
|
||||||
|
for _, sv := range typedV {
|
||||||
|
typedE, ok := sv.(map[string]interface{})
|
||||||
|
if !ok {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
if hasDeleteDirectiveMarker(typedE) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user